Release 1.5.29.
[wine] / dlls / msi / tests / action.c
1 /*
2  * Copyright (C) 2006 James Hawkins
3  * Copyright 2010 Hans Leidekker for CodeWeavers
4  *
5  * Tests concentrating on standard actions
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #define _WIN32_MSI 300
23 #include <stdio.h>
24
25 #include <windows.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <msi.h>
29 #include <fci.h>
30 #include <srrestoreptapi.h>
31
32 #include "wine/test.h"
33
34 static UINT (WINAPI *pMsiQueryComponentStateA)
35     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *);
36 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
37     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
38 static UINT (WINAPI *pMsiSourceListGetInfoA)
39     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
40 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
41     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiQueryFeatureStateExA)
43     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *);
44
45 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR *);
46 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE);
47 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
48 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
49
50 static HMODULE hsrclient;
51 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
52 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA *, STATEMGRSTATUS *);
53
54 static BOOL is_wow64;
55 static const BOOL is_64bit = sizeof(void *) > sizeof(int);
56
57 static const char *msifile = "msitest.msi";
58 static CHAR CURR_DIR[MAX_PATH];
59 static CHAR PROG_FILES_DIR[MAX_PATH];
60 static CHAR COMMON_FILES_DIR[MAX_PATH];
61 static CHAR APP_DATA_DIR[MAX_PATH];
62 static CHAR WINDOWS_DIR[MAX_PATH];
63
64 /* msi database data */
65
66 static const char component_dat[] =
67     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
68     "s72\tS38\ts72\ti2\tS255\tS72\n"
69     "Component\tComponent\n"
70     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
71     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
72     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
73     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
74     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
75     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
76     "component\t\tMSITESTDIR\t0\t1\tfile\n"
77     "service_comp\t{935A0A91-22A3-4F87-BCA8-928FFDFE2353}\tMSITESTDIR\t0\t\tservice_file\n"
78     "service_comp2\t{3F7B04A4-9521-4649-BDC9-0C8722740A49}\tMSITESTDIR\t0\t\tservice_file2";
79
80 static const char directory_dat[] =
81     "Directory\tDirectory_Parent\tDefaultDir\n"
82     "s72\tS72\tl255\n"
83     "Directory\tDirectory\n"
84     "CABOUTDIR\tMSITESTDIR\tcabout\n"
85     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
86     "FIRSTDIR\tMSITESTDIR\tfirst\n"
87     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
88     "NEWDIR\tCABOUTDIR\tnew\n"
89     "ProgramFilesFolder\tTARGETDIR\t.\n"
90     "TARGETDIR\t\tSourceDir";
91
92 static const char feature_dat[] =
93     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
94     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
95     "Feature\tFeature\n"
96     "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
97     "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
98     "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
99     "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
100     "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
101     "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
102     "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
103
104 static const char feature_comp_dat[] =
105     "Feature_\tComponent_\n"
106     "s38\ts72\n"
107     "FeatureComponents\tFeature_\tComponent_\n"
108     "Five\tFive\n"
109     "Four\tFour\n"
110     "One\tOne\n"
111     "Three\tThree\n"
112     "Two\tTwo\n"
113     "feature\tcomponent\n"
114     "service_feature\tservice_comp\n"
115     "service_feature\tservice_comp2";
116
117 static const char file_dat[] =
118     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
119     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
120     "File\tFile\n"
121     "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
122     "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
123     "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
124     "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
125     "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
126     "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
127     "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t6\n"
128     "service_file2\tservice_comp2\tservice2.exe\t100\t\t\t8192\t7";
129
130 static const char install_exec_seq_dat[] =
131     "Action\tCondition\tSequence\n"
132     "s72\tS255\tI2\n"
133     "InstallExecuteSequence\tAction\n"
134     "AllocateRegistrySpace\tNOT Installed\t1550\n"
135     "CostFinalize\t\t1000\n"
136     "CostInitialize\t\t800\n"
137     "FileCost\t\t900\n"
138     "ResolveSource\t\t950\n"
139     "MoveFiles\t\t1700\n"
140     "InstallFiles\t\t4000\n"
141     "DuplicateFiles\t\t4500\n"
142     "WriteEnvironmentStrings\t\t4550\n"
143     "CreateShortcuts\t\t4600\n"
144     "InstallServices\t\t5000\n"
145     "InstallFinalize\t\t6600\n"
146     "InstallInitialize\t\t1500\n"
147     "InstallValidate\t\t1400\n"
148     "LaunchConditions\t\t100\n"
149     "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
150
151 static const char media_dat[] =
152     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
153     "i2\ti4\tL64\tS255\tS32\tS72\n"
154     "Media\tDiskId\n"
155     "1\t3\t\t\tDISK1\t\n"
156     "2\t7\t\tmsitest.cab\tDISK2\t\n";
157
158 static const char property_dat[] =
159     "Property\tValue\n"
160     "s72\tl0\n"
161     "Property\tProperty\n"
162     "DefaultUIFont\tDlgFont8\n"
163     "HASUIRUN\t0\n"
164     "INSTALLLEVEL\t3\n"
165     "InstallMode\tTypical\n"
166     "Manufacturer\tWine\n"
167     "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
168     "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
169     "ProductID\tnone\n"
170     "ProductLanguage\t1033\n"
171     "ProductName\tMSITEST\n"
172     "ProductVersion\t1.1.1\n"
173     "PROMPTROLLBACKCOST\tP\n"
174     "Setup\tSetup\n"
175     "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
176     "AdminProperties\tPOSTADMIN\n"
177     "ROOTDRIVE\tC:\\\n"
178     "SERVNAME\tTestService\n"
179     "SERVNAME2\tTestService2\n"
180     "SERVDISP\tTestServiceDisp\n"
181     "SERVDISP2\tTestServiceDisp2\n"
182     "MSIFASTINSTALL\t1\n";
183
184 static const char environment_dat[] =
185     "Environment\tName\tValue\tComponent_\n"
186     "s72\tl255\tL255\ts72\n"
187     "Environment\tEnvironment\n"
188     "Var1\t=-MSITESTVAR1\t1\tOne\n"
189     "Var2\tMSITESTVAR2\t1\tOne\n"
190     "Var3\t=-MSITESTVAR3\t1\tOne\n"
191     "Var4\tMSITESTVAR4\t1\tOne\n"
192     "Var5\t-MSITESTVAR5\t\tOne\n"
193     "Var6\tMSITESTVAR6\t\tOne\n"
194     "Var7\t!-MSITESTVAR7\t\tOne\n"
195     "Var8\t!-*MSITESTVAR8\t\tOne\n"
196     "Var9\t=-MSITESTVAR9\t\tOne\n"
197     "Var10\t=MSITESTVAR10\t\tOne\n"
198     "Var11\t+-MSITESTVAR11\t[~];1\tOne\n"
199     "Var12\t+-MSITESTVAR11\t[~];2\tOne\n"
200     "Var13\t+-MSITESTVAR12\t[~];1\tOne\n"
201     "Var14\t=MSITESTVAR13\t[~];1\tOne\n"
202     "Var15\t=MSITESTVAR13\t[~];2\tOne\n"
203     "Var16\t=MSITESTVAR14\t;1;\tOne\n"
204     "Var17\t=MSITESTVAR15\t;;1;;\tOne\n"
205     "Var18\t=MSITESTVAR16\t 1 \tOne\n"
206     "Var19\t+-MSITESTVAR17\t1\tOne\n"
207     "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n"
208     "Var21\t+-MSITESTVAR18\t1\tOne\n"
209     "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n"
210     "Var23\t+-MSITESTVAR19\t1\tOne\n"
211     "Var24\t+-MSITESTVAR19\t[~]2\tOne\n"
212     "Var25\t+-MSITESTVAR20\t1\tOne\n"
213     "Var26\t+-MSITESTVAR20\t2[~]\tOne\n";
214
215 static const char service_install_dat[] =
216     "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
217     "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
218     "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
219     "ServiceInstall\tServiceInstall\n"
220     "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService\t\t-a arg\tservice_comp\tdescription\n"
221     "TestService2\tSERVNAME2]\t[SERVDISP2]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService2\t\t-a arg\tservice_comp2\tdescription";
222
223 static const char service_control_dat[] =
224     "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
225     "s72\tl255\ti2\tL255\tI2\ts72\n"
226     "ServiceControl\tServiceControl\n"
227     "ServiceControl\tTestService3\t8\t\t0\tservice_comp\n"
228     "ServiceControl2\tTestService3\t128\t\t0\tservice_comp2";
229
230 static const char sss_service_control_dat[] =
231     "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
232     "s72\tl255\ti2\tL255\tI2\ts72\n"
233     "ServiceControl\tServiceControl\n"
234     "ServiceControl\tSpooler\t1\t\t0\tservice_comp";
235
236 static const char sss_install_exec_seq_dat[] =
237     "Action\tCondition\tSequence\n"
238     "s72\tS255\tI2\n"
239     "InstallExecuteSequence\tAction\n"
240     "LaunchConditions\t\t100\n"
241     "CostInitialize\t\t800\n"
242     "FileCost\t\t900\n"
243     "ResolveSource\t\t950\n"
244     "CostFinalize\t\t1000\n"
245     "InstallValidate\t\t1400\n"
246     "InstallInitialize\t\t1500\n"
247     "DeleteServices\t\t5000\n"
248     "MoveFiles\t\t5100\n"
249     "InstallFiles\t\t5200\n"
250     "DuplicateFiles\t\t5300\n"
251     "StartServices\t\t5400\n"
252     "InstallFinalize\t\t6000\n";
253
254 static const char sds_install_exec_seq_dat[] =
255     "Action\tCondition\tSequence\n"
256     "s72\tS255\tI2\n"
257     "InstallExecuteSequence\tAction\n"
258     "LaunchConditions\t\t100\n"
259     "CostInitialize\t\t800\n"
260     "FileCost\t\t900\n"
261     "ResolveSource\t\t950\n"
262     "CostFinalize\t\t1000\n"
263     "InstallValidate\t\t1400\n"
264     "InstallInitialize\t\t1500\n"
265     "StopServices\t\t5000\n"
266     "DeleteServices\t\t5050\n"
267     "MoveFiles\t\t5100\n"
268     "InstallFiles\t\t5200\n"
269     "DuplicateFiles\t\t5300\n"
270     "InstallServices\t\t5400\n"
271     "StartServices\t\t5450\n"
272     "RegisterProduct\t\t5500\n"
273     "PublishFeatures\t\t5600\n"
274     "PublishProduct\t\t5700\n"
275     "InstallFinalize\t\t6000\n";
276
277 static const char rof_component_dat[] =
278     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
279     "s72\tS38\ts72\ti2\tS255\tS72\n"
280     "Component\tComponent\n"
281     "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
282
283 static const char rof_feature_dat[] =
284     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
285     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
286     "Feature\tFeature\n"
287     "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
288     "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
289
290 static const char rof_feature_comp_dat[] =
291     "Feature_\tComponent_\n"
292     "s38\ts72\n"
293     "FeatureComponents\tFeature_\tComponent_\n"
294     "feature\tmaximus\n"
295     "montecristo\tmaximus";
296
297 static const char rof_file_dat[] =
298     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
299     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
300     "File\tFile\n"
301     "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
302
303 static const char rof_media_dat[] =
304     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
305     "i2\ti4\tL64\tS255\tS32\tS72\n"
306     "Media\tDiskId\n"
307     "1\t1\t\t\tDISK1\t\n";
308
309 static const char ci2_feature_comp_dat[] =
310     "Feature_\tComponent_\n"
311     "s38\ts72\n"
312     "FeatureComponents\tFeature_\tComponent_\n"
313     "feature\taugustus";
314
315 static const char ci2_file_dat[] =
316     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
317     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
318     "File\tFile\n"
319     "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
320
321 static const char pp_install_exec_seq_dat[] =
322     "Action\tCondition\tSequence\n"
323     "s72\tS255\tI2\n"
324     "InstallExecuteSequence\tAction\n"
325     "ValidateProductID\t\t700\n"
326     "CostInitialize\t\t800\n"
327     "FileCost\t\t900\n"
328     "CostFinalize\t\t1000\n"
329     "InstallValidate\t\t1400\n"
330     "InstallInitialize\t\t1500\n"
331     "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
332     "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
333     "RemoveFiles\t\t3500\n"
334     "InstallFiles\t\t4000\n"
335     "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
336     "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
337     "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
338     "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
339     "InstallFinalize\t\t6600";
340
341 static const char pp_component_dat[] =
342     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
343     "s72\tS38\ts72\ti2\tS255\tS72\n"
344     "Component\tComponent\n"
345     "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\t\tmaximus\n";
346
347 static const char ppc_component_dat[] =
348     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
349     "s72\tS38\ts72\ti2\tS255\tS72\n"
350     "Component\tComponent\n"
351     "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\t\tmaximus\n"
352     "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n";
353
354 static const char ppc_file_dat[] =
355     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
356     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
357     "File\tFile\n"
358     "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n"
359     "augustus\taugustus\taugustus\t500\t\t\t8192\t2";
360
361 static const char ppc_media_dat[] =
362     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
363     "i2\ti4\tL64\tS255\tS32\tS72\n"
364     "Media\tDiskId\n"
365     "1\t2\t\t\tDISK1\t\n";
366
367 static const char ppc_feature_comp_dat[] =
368     "Feature_\tComponent_\n"
369     "s38\ts72\n"
370     "FeatureComponents\tFeature_\tComponent_\n"
371     "feature\tmaximus\n"
372     "feature\taugustus\n"
373     "montecristo\tmaximus";
374
375 static const char cwd_component_dat[] =
376     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
377     "s72\tS38\ts72\ti2\tS255\tS72\n"
378     "Component\tComponent\n"
379     "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
380
381 static const char rem_component_dat[] =
382     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
383     "s72\tS38\ts72\ti2\tS255\tS72\n"
384     "Component\tComponent\n"
385     "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
386     "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
387     "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
388
389 static const char rem_feature_comp_dat[] =
390     "Feature_\tComponent_\n"
391     "s38\ts72\n"
392     "FeatureComponents\tFeature_\tComponent_\n"
393     "feature\thydrogen\n"
394     "feature\thelium\n"
395     "feature\tlithium";
396
397 static const char rem_file_dat[] =
398     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
399     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
400     "File\tFile\n"
401     "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
402     "helium\thelium\thelium\t0\t\t\t8192\t1\n"
403     "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
404
405 static const char rem_install_exec_seq_dat[] =
406     "Action\tCondition\tSequence\n"
407     "s72\tS255\tI2\n"
408     "InstallExecuteSequence\tAction\n"
409     "ValidateProductID\t\t700\n"
410     "CostInitialize\t\t800\n"
411     "FileCost\t\t900\n"
412     "CostFinalize\t\t1000\n"
413     "InstallValidate\t\t1400\n"
414     "InstallInitialize\t\t1500\n"
415     "ProcessComponents\t\t1600\n"
416     "UnpublishFeatures\t\t1800\n"
417     "RemoveFiles\t\t3500\n"
418     "InstallFiles\t\t4000\n"
419     "RegisterProduct\t\t6100\n"
420     "PublishFeatures\t\t6300\n"
421     "PublishProduct\t\t6400\n"
422     "InstallFinalize\t\t6600";
423
424 static const char rem_remove_files_dat[] =
425     "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
426     "s72\ts72\tS255\ts72\tI2\n"
427     "RemoveFile\tFileKey\n"
428     "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
429     "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
430     "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
431     "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
432     "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
433     "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
434     "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
435     "block\thelium\tblock\tMSITESTDIR\t3\n"
436     "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n"
437     "nanoacre\thydrogen\t\tCABOUTDIR\t3\n";
438
439 static const char mov_move_file_dat[] =
440     "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
441     "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
442     "MoveFile\tFileKey\n"
443     "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
444     "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
445     "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
446     "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
447     "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
448     "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
449     "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
450     "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
451     "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
452     "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
453     "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
454     "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
455     "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
456     "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n"
457     "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
458     "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
459     "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
460     "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
461
462 static const char df_directory_dat[] =
463     "Directory\tDirectory_Parent\tDefaultDir\n"
464     "s72\tS72\tl255\n"
465     "Directory\tDirectory\n"
466     "THIS\tMSITESTDIR\tthis\n"
467     "DOESNOT\tTHIS\tdoesnot\n"
468     "NONEXISTENT\tDOESNOT\texist\n"
469     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
470     "ProgramFilesFolder\tTARGETDIR\t.\n"
471     "TARGETDIR\t\tSourceDir";
472
473 static const char df_duplicate_file_dat[] =
474     "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
475     "s72\ts72\ts72\tS255\tS72\n"
476     "DuplicateFile\tFileKey\n"
477     "maximus\tmaximus\tmaximus\taugustus\t\n"
478     "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n"
479     "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n";
480
481 static const char wrv_component_dat[] =
482     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
483     "s72\tS38\ts72\ti2\tS255\tS72\n"
484     "Component\tComponent\n"
485     "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
486
487 static const char wrv_registry_dat[] =
488     "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
489     "s72\ti2\tl255\tL255\tL0\ts72\n"
490     "Registry\tRegistry\n"
491     "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus\n"
492     "regdata1\t2\tSOFTWARE\\Wine\\msitest\t*\t\taugustus\n"
493     "regdata2\t2\tSOFTWARE\\Wine\\msitest\t*\t#%\taugustus\n"
494     "regdata3\t2\tSOFTWARE\\Wine\\msitest\t*\t#x\taugustus\n"
495     "regdata4\t2\tSOFTWARE\\Wine\\msitest\\VisualStudio\\10.0\\AD7Metrics\\Exception\\{049EC4CC-30D2-4032-9256-EE18EB41B62B}\\Common Language Runtime Exceptions\\System.Workflow.ComponentModel.Serialization\\System.Workflow.ComponentModel.Serialization.WorkflowMarkupSerializationException\tlong\tkey\taugustus\n"
496     "regdata5\t2\tSOFTWARE\\Wine\\msitest\tValue1\t[~]one[~]\taugustus\n"
497     "regdata6\t2\tSOFTWARE\\Wine\\msitest\tValue2\t[~]two\taugustus\n"
498     "regdata7\t2\tSOFTWARE\\Wine\\msitest\tValue3\tone[~]\taugustus\n"
499     "regdata8\t2\tSOFTWARE\\Wine\\msitest\tValue4\tone[~]two\taugustus\n"
500     "regdata9\t2\tSOFTWARE\\Wine\\msitest\tValue5\t[~]one[~]two[~]three\taugustus\n"
501     "regdata10\t2\tSOFTWARE\\Wine\\msitest\tValue6\t[~]\taugustus\n"
502     "regdata11\t2\tSOFTWARE\\Wine\\msitest\tValue7\t[~]two\taugustus\n";
503
504 static const char cf_directory_dat[] =
505     "Directory\tDirectory_Parent\tDefaultDir\n"
506     "s72\tS72\tl255\n"
507     "Directory\tDirectory\n"
508     "FIRSTDIR\tMSITESTDIR\tfirst\n"
509     "SECONDDIR\tMSITESTDIR\tsecond\n"
510     "THIRDDIR\tMSITESTDIR\tthird\n"
511     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
512     "ProgramFilesFolder\tTARGETDIR\t.\n"
513     "TARGETDIR\t\tSourceDir";
514
515 static const char cf_component_dat[] =
516     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
517     "s72\tS38\ts72\ti2\tS255\tS72\n"
518     "Component\tComponent\n"
519     "One\t{F8CD42AC-9C38-48FE-8664-B35FD121012A}\tFIRSTDIR\t0\t\tone.txt\n"
520     "Two\t{DE2DB02E-2DDF-4E34-8CF6-DCA13E29DF52}\tSECONDDIR\t0\t\ttwo.txt\n";
521
522 static const char cf_feature_dat[] =
523     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
524     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
525     "Feature\tFeature\n"
526     "One\t\tOne\tThe One Feature\t1\t3\tFIRSTDIR\t0\n"
527     "Two\t\tTwo\tThe Two Feature\t1\t3\tSECONDDIR\t0\n";
528
529 static const char cf_feature_comp_dat[] =
530     "Feature_\tComponent_\n"
531     "s38\ts72\n"
532     "FeatureComponents\tFeature_\tComponent_\n"
533     "One\tOne\n"
534     "Two\tTwo\n";
535
536 static const char cf_file_dat[] =
537     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
538     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
539     "File\tFile\n"
540     "one.txt\tOne\tone.txt\t0\t\t\t0\t1\n"
541     "two.txt\tTwo\ttwo.txt\t0\t\t\t0\t2\n";
542
543 static const char cf_create_folders_dat[] =
544     "Directory_\tComponent_\n"
545     "s72\ts72\n"
546     "CreateFolder\tDirectory_\tComponent_\n"
547     "FIRSTDIR\tOne\n"
548     "SECONDDIR\tTwo\n"
549     "THIRDDIR\tTwo\n";
550
551 static const char cf_install_exec_seq_dat[] =
552     "Action\tCondition\tSequence\n"
553     "s72\tS255\tI2\n"
554     "InstallExecuteSequence\tAction\n"
555     "CostFinalize\t\t1000\n"
556     "ValidateProductID\t\t700\n"
557     "CostInitialize\t\t800\n"
558     "FileCost\t\t900\n"
559     "RemoveFiles\t\t3500\n"
560     "CreateFolders\t\t3700\n"
561     "RemoveFolders\t\t3800\n"
562     "InstallFiles\t\t4000\n"
563     "RegisterUser\t\t6000\n"
564     "RegisterProduct\t\t6100\n"
565     "PublishFeatures\t\t6300\n"
566     "PublishProduct\t\t6400\n"
567     "InstallFinalize\t\t6600\n"
568     "InstallInitialize\t\t1500\n"
569     "ProcessComponents\t\t1600\n"
570     "UnpublishFeatures\t\t1800\n"
571     "InstallValidate\t\t1400\n"
572     "LaunchConditions\t\t100\n";
573
574 static const char sr_selfreg_dat[] =
575     "File_\tCost\n"
576     "s72\tI2\n"
577     "SelfReg\tFile_\n"
578     "one.txt\t1\n";
579
580 static const char sr_install_exec_seq_dat[] =
581     "Action\tCondition\tSequence\n"
582     "s72\tS255\tI2\n"
583     "InstallExecuteSequence\tAction\n"
584     "CostFinalize\t\t1000\n"
585     "CostInitialize\t\t800\n"
586     "FileCost\t\t900\n"
587     "ResolveSource\t\t950\n"
588     "MoveFiles\t\t1700\n"
589     "SelfUnregModules\t\t3900\n"
590     "InstallFiles\t\t4000\n"
591     "DuplicateFiles\t\t4500\n"
592     "WriteEnvironmentStrings\t\t4550\n"
593     "CreateShortcuts\t\t4600\n"
594     "InstallFinalize\t\t6600\n"
595     "InstallInitialize\t\t1500\n"
596     "InstallValidate\t\t1400\n"
597     "LaunchConditions\t\t100\n";
598
599 static const char font_media_dat[] =
600     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
601     "i2\ti4\tL64\tS255\tS32\tS72\n"
602     "Media\tDiskId\n"
603     "1\t3\t\t\tDISK1\t\n";
604
605 static const char font_file_dat[] =
606     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
607     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
608     "File\tFile\n"
609     "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n";
610
611 static const char font_feature_dat[] =
612     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
613     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
614     "Feature\tFeature\n"
615     "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n";
616
617 static const char font_component_dat[] =
618     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
619     "s72\tS38\ts72\ti2\tS255\tS72\n"
620     "Component\tComponent\n"
621     "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n";
622
623 static const char font_feature_comp_dat[] =
624     "Feature_\tComponent_\n"
625     "s38\ts72\n"
626     "FeatureComponents\tFeature_\tComponent_\n"
627     "fonts\tfonts\n";
628
629 static const char font_dat[] =
630     "File_\tFontTitle\n"
631     "s72\tS128\n"
632     "Font\tFile_\n"
633     "font.ttf\tmsi test font\n";
634
635 static const char font_install_exec_seq_dat[] =
636     "Action\tCondition\tSequence\n"
637     "s72\tS255\tI2\n"
638     "InstallExecuteSequence\tAction\n"
639     "ValidateProductID\t\t700\n"
640     "CostInitialize\t\t800\n"
641     "FileCost\t\t900\n"
642     "CostFinalize\t\t1000\n"
643     "InstallValidate\t\t1400\n"
644     "InstallInitialize\t\t1500\n"
645     "ProcessComponents\t\t1600\n"
646     "UnpublishFeatures\t\t1800\n"
647     "RemoveFiles\t\t3500\n"
648     "InstallFiles\t\t4000\n"
649     "RegisterFonts\t\t4100\n"
650     "UnregisterFonts\t\t4200\n"
651     "RegisterUser\t\t6000\n"
652     "RegisterProduct\t\t6100\n"
653     "PublishFeatures\t\t6300\n"
654     "PublishProduct\t\t6400\n"
655     "InstallFinalize\t\t6600";
656
657 static const char vp_property_dat[] =
658     "Property\tValue\n"
659     "s72\tl0\n"
660     "Property\tProperty\n"
661     "HASUIRUN\t0\n"
662     "INSTALLLEVEL\t3\n"
663     "InstallMode\tTypical\n"
664     "Manufacturer\tWine\n"
665     "PIDTemplate\t###-#######\n"
666     "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
667     "ProductLanguage\t1033\n"
668     "ProductName\tMSITEST\n"
669     "ProductVersion\t1.1.1\n"
670     "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
671     "MSIFASTINSTALL\t1\n";
672
673 static const char vp_custom_action_dat[] =
674     "Action\tType\tSource\tTarget\tISComments\n"
675     "s72\ti2\tS64\tS0\tS255\n"
676     "CustomAction\tAction\n"
677     "SetProductID1\t51\tProductID\t1\t\n"
678     "SetProductID2\t51\tProductID\t2\t\n"
679     "TestProductID1\t19\t\t\tHalts installation\n"
680     "TestProductID2\t19\t\t\tHalts installation\n";
681
682 static const char vp_install_exec_seq_dat[] =
683     "Action\tCondition\tSequence\n"
684     "s72\tS255\tI2\n"
685     "InstallExecuteSequence\tAction\n"
686     "LaunchConditions\t\t100\n"
687     "CostInitialize\t\t800\n"
688     "FileCost\t\t900\n"
689     "CostFinalize\t\t1000\n"
690     "InstallValidate\t\t1400\n"
691     "InstallInitialize\t\t1500\n"
692     "SetProductID1\tSET_PRODUCT_ID=1\t3000\n"
693     "SetProductID2\tSET_PRODUCT_ID=2\t3100\n"
694     "ValidateProductID\t\t3200\n"
695     "InstallExecute\t\t3300\n"
696     "TestProductID1\tProductID=1\t3400\n"
697     "TestProductID2\tProductID=\"123-1234567\"\t3500\n"
698     "InstallFiles\t\t4000\n"
699     "InstallFinalize\t\t6000\n";
700
701 static const char odbc_file_dat[] =
702     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
703     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
704     "File\tFile\n"
705     "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n"
706     "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n"
707     "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n"
708     "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n"
709     "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n";
710
711 static const char odbc_feature_dat[] =
712     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
713     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
714     "Feature\tFeature\n"
715     "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n";
716
717 static const char odbc_feature_comp_dat[] =
718     "Feature_\tComponent_\n"
719     "s38\ts72\n"
720     "FeatureComponents\tFeature_\tComponent_\n"
721     "odbc\todbc\n";
722
723 static const char odbc_component_dat[] =
724     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
725     "s72\tS38\ts72\ti2\tS255\tS72\n"
726     "Component\tComponent\n"
727     "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n";
728
729 static const char odbc_driver_dat[] =
730     "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n"
731     "s72\ts72\ts255\ts72\tS72\n"
732     "ODBCDriver\tDriver\n"
733     "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n"
734     "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n";
735
736 static const char odbc_translator_dat[] =
737     "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n"
738     "s72\ts72\ts255\ts72\tS72\n"
739     "ODBCTranslator\tTranslator\n"
740     "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n"
741     "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n";
742
743 static const char odbc_datasource_dat[] =
744     "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n"
745     "s72\ts72\ts255\ts255\ti2\n"
746     "ODBCDataSource\tDataSource\n"
747     "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n";
748
749 static const char odbc_install_exec_seq_dat[] =
750     "Action\tCondition\tSequence\n"
751     "s72\tS255\tI2\n"
752     "InstallExecuteSequence\tAction\n"
753     "LaunchConditions\t\t100\n"
754     "CostInitialize\t\t800\n"
755     "FileCost\t\t900\n"
756     "CostFinalize\t\t1000\n"
757     "InstallValidate\t\t1400\n"
758     "InstallInitialize\t\t1500\n"
759     "ProcessComponents\t\t1600\n"
760     "InstallODBC\t\t3000\n"
761     "RemoveODBC\t\t3100\n"
762     "RemoveFiles\t\t3900\n"
763     "InstallFiles\t\t4000\n"
764     "RegisterProduct\t\t5000\n"
765     "PublishFeatures\t\t5100\n"
766     "PublishProduct\t\t5200\n"
767     "InstallFinalize\t\t6000\n";
768
769 static const char odbc_media_dat[] =
770     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
771     "i2\ti4\tL64\tS255\tS32\tS72\n"
772     "Media\tDiskId\n"
773     "1\t5\t\t\tDISK1\t\n";
774
775 static const char tl_file_dat[] =
776     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
777     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
778     "File\tFile\n"
779     "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n";
780
781 static const char tl_feature_dat[] =
782     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
783     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
784     "Feature\tFeature\n"
785     "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n";
786
787 static const char tl_feature_comp_dat[] =
788     "Feature_\tComponent_\n"
789     "s38\ts72\n"
790     "FeatureComponents\tFeature_\tComponent_\n"
791     "typelib\ttypelib\n";
792
793 static const char tl_component_dat[] =
794     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
795     "s72\tS38\ts72\ti2\tS255\tS72\n"
796     "Component\tComponent\n"
797     "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n";
798
799 static const char tl_typelib_dat[] =
800     "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n"
801     "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n"
802     "TypeLib\tLibID\tLanguage\tComponent_\n"
803     "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n";
804
805 static const char tl_install_exec_seq_dat[] =
806     "Action\tCondition\tSequence\n"
807     "s72\tS255\tI2\n"
808     "InstallExecuteSequence\tAction\n"
809     "LaunchConditions\t\t100\n"
810     "CostInitialize\t\t800\n"
811     "FileCost\t\t900\n"
812     "CostFinalize\t\t1000\n"
813     "InstallValidate\t\t1400\n"
814     "InstallInitialize\t\t1500\n"
815     "ProcessComponents\t\t1600\n"
816     "RemoveFiles\t\t1700\n"
817     "InstallFiles\t\t2000\n"
818     "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n"
819     "UnregisterTypeLibraries\t\t3100\n"
820     "RegisterProduct\t\t5100\n"
821     "PublishFeatures\t\t5200\n"
822     "PublishProduct\t\t5300\n"
823     "InstallFinalize\t\t6000\n";
824
825 static const char crs_file_dat[] =
826     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
827     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
828     "File\tFile\n"
829     "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n";
830
831 static const char crs_feature_dat[] =
832     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
833     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
834     "Feature\tFeature\n"
835     "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n";
836
837 static const char crs_feature_comp_dat[] =
838     "Feature_\tComponent_\n"
839     "s38\ts72\n"
840     "FeatureComponents\tFeature_\tComponent_\n"
841     "shortcut\tshortcut\n";
842
843 static const char crs_component_dat[] =
844     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
845     "s72\tS38\ts72\ti2\tS255\tS72\n"
846     "Component\tComponent\n"
847     "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n";
848
849 static const char crs_shortcut_dat[] =
850     "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
851     "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n"
852     "Shortcut\tShortcut\n"
853     "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n";
854
855 static const char crs_install_exec_seq_dat[] =
856     "Action\tCondition\tSequence\n"
857     "s72\tS255\tI2\n"
858     "InstallExecuteSequence\tAction\n"
859     "LaunchConditions\t\t100\n"
860     "CostInitialize\t\t800\n"
861     "FileCost\t\t900\n"
862     "CostFinalize\t\t1000\n"
863     "InstallValidate\t\t1400\n"
864     "InstallInitialize\t\t1500\n"
865     "ProcessComponents\t\t1600\n"
866     "RemoveFiles\t\t1700\n"
867     "InstallFiles\t\t2000\n"
868     "RemoveShortcuts\t\t3000\n"
869     "CreateShortcuts\t\t3100\n"
870     "RegisterProduct\t\t5000\n"
871     "PublishFeatures\t\t5100\n"
872     "PublishProduct\t\t5200\n"
873     "InstallFinalize\t\t6000\n";
874
875 static const char pub_file_dat[] =
876     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
877     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
878     "File\tFile\n"
879     "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n";
880
881 static const char pub_feature_dat[] =
882     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
883     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
884     "Feature\tFeature\n"
885     "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n";
886
887 static const char pub_feature_comp_dat[] =
888     "Feature_\tComponent_\n"
889     "s38\ts72\n"
890     "FeatureComponents\tFeature_\tComponent_\n"
891     "publish\tpublish\n";
892
893 static const char pub_component_dat[] =
894     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
895     "s72\tS38\ts72\ti2\tS255\tS72\n"
896     "Component\tComponent\n"
897     "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n";
898
899 static const char pub_publish_component_dat[] =
900     "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n"
901     "s38\ts255\ts72\tL255\ts38\n"
902     "PublishComponent\tComponentId\tQualifier\tComponent_\n"
903     "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n";
904
905 static const char pub_install_exec_seq_dat[] =
906     "Action\tCondition\tSequence\n"
907     "s72\tS255\tI2\n"
908     "InstallExecuteSequence\tAction\n"
909     "LaunchConditions\t\t100\n"
910     "CostInitialize\t\t800\n"
911     "FileCost\t\t900\n"
912     "CostFinalize\t\t1000\n"
913     "InstallValidate\t\t1400\n"
914     "InstallInitialize\t\t1500\n"
915     "ProcessComponents\t\t1600\n"
916     "RemoveFiles\t\t1700\n"
917     "InstallFiles\t\t2000\n"
918     "PublishComponents\t\t3000\n"
919     "UnpublishComponents\t\t3100\n"
920     "RegisterProduct\t\t5000\n"
921     "PublishFeatures\t\t5100\n"
922     "PublishProduct\t\t5200\n"
923     "InstallFinalize\t\t6000\n";
924
925 static const char rd_file_dat[] =
926     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
927     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
928     "File\tFile\n"
929     "original.txt\tduplicate\toriginal.txt\t1000\t\t\t8192\t1\n"
930     "original2.txt\tduplicate\toriginal2.txt\t1000\t\t\t8192\t2\n"
931     "original3.txt\tduplicate2\toriginal3.txt\t1000\t\t\t8192\t3\n";
932
933 static const char rd_feature_dat[] =
934     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
935     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
936     "Feature\tFeature\n"
937     "duplicate\t\t\tduplicate feature\t1\t2\tMSITESTDIR\t0\n";
938
939 static const char rd_feature_comp_dat[] =
940     "Feature_\tComponent_\n"
941     "s38\ts72\n"
942     "FeatureComponents\tFeature_\tComponent_\n"
943     "duplicate\tduplicate\n";
944
945 static const char rd_component_dat[] =
946     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
947     "s72\tS38\ts72\ti2\tS255\tS72\n"
948     "Component\tComponent\n"
949     "duplicate\t{EB45D06A-ADFE-44E3-8D41-B7DE150E41AD}\tMSITESTDIR\t0\t\toriginal.txt\n"
950     "duplicate2\t{B8BA60E0-B2E9-488E-9D0E-E60F25F04F97}\tMSITESTDIR\t0\tDUPLICATE2=1\toriginal3.txt\n";
951
952 static const char rd_duplicate_file_dat[] =
953     "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
954     "s72\ts72\ts72\tS255\tS72\n"
955     "DuplicateFile\tFileKey\n"
956     "duplicate\tduplicate\toriginal.txt\tduplicate.txt\t\n"
957     "duplicate2\tduplicate\toriginal2.txt\t\tMSITESTDIR\n"
958     "duplicate3\tduplicate2\toriginal3.txt\tduplicate2.txt\t\n";
959
960 static const char rd_install_exec_seq_dat[] =
961     "Action\tCondition\tSequence\n"
962     "s72\tS255\tI2\n"
963     "InstallExecuteSequence\tAction\n"
964     "LaunchConditions\t\t100\n"
965     "CostInitialize\t\t800\n"
966     "FileCost\t\t900\n"
967     "CostFinalize\t\t1000\n"
968     "InstallValidate\t\t1400\n"
969     "InstallInitialize\t\t1500\n"
970     "ProcessComponents\t\t1600\n"
971     "RemoveDuplicateFiles\t\t1900\n"
972     "InstallFiles\t\t2000\n"
973     "DuplicateFiles\t\t2100\n"
974     "RegisterProduct\t\t5000\n"
975     "PublishFeatures\t\t5100\n"
976     "PublishProduct\t\t5200\n"
977     "InstallFinalize\t\t6000\n";
978
979 static const char rrv_file_dat[] =
980     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
981     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
982     "File\tFile\n"
983     "registry.txt\tregistry\tregistry.txt\t1000\t\t\t8192\t1\n";
984
985 static const char rrv_feature_dat[] =
986     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
987     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
988     "Feature\tFeature\n"
989     "registry\t\t\tregistry feature\t1\t2\tMSITESTDIR\t0\n";
990
991 static const char rrv_feature_comp_dat[] =
992     "Feature_\tComponent_\n"
993     "s38\ts72\n"
994     "FeatureComponents\tFeature_\tComponent_\n"
995     "registry\tregistry\n";
996
997 static const char rrv_component_dat[] =
998     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
999     "s72\tS38\ts72\ti2\tS255\tS72\n"
1000     "Component\tComponent\n"
1001     "registry\t{DA97585B-962D-45EB-AD32-DA15E60CA9EE}\tMSITESTDIR\t0\t\tregistry.txt\n";
1002
1003 static const char rrv_registry_dat[] =
1004     "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
1005     "s72\ti2\tl255\tL255\tL0\ts72\n"
1006     "Registry\tRegistry\n"
1007     "reg1\t2\tSOFTWARE\\Wine\\keyA\t\tA\tregistry\n"
1008     "reg2\t2\tSOFTWARE\\Wine\\keyA\tvalueA\tA\tregistry\n"
1009     "reg3\t2\tSOFTWARE\\Wine\\key1\t-\t\tregistry\n";
1010
1011 static const char rrv_remove_registry_dat[] =
1012     "RemoveRegistry\tRoot\tKey\tName\tComponent_\n"
1013     "s72\ti2\tl255\tL255\ts72\n"
1014     "RemoveRegistry\tRemoveRegistry\n"
1015     "reg1\t2\tSOFTWARE\\Wine\\keyB\t\tregistry\n"
1016     "reg2\t2\tSOFTWARE\\Wine\\keyB\tValueB\tregistry\n"
1017     "reg3\t2\tSOFTWARE\\Wine\\key2\t-\tregistry\n";
1018
1019 static const char rrv_install_exec_seq_dat[] =
1020     "Action\tCondition\tSequence\n"
1021     "s72\tS255\tI2\n"
1022     "InstallExecuteSequence\tAction\n"
1023     "LaunchConditions\t\t100\n"
1024     "CostInitialize\t\t800\n"
1025     "FileCost\t\t900\n"
1026     "CostFinalize\t\t1000\n"
1027     "InstallValidate\t\t1400\n"
1028     "InstallInitialize\t\t1500\n"
1029     "ProcessComponents\t\t1600\n"
1030     "RemoveFiles\t\t1700\n"
1031     "InstallFiles\t\t2000\n"
1032     "RemoveRegistryValues\t\t3000\n"
1033     "RegisterProduct\t\t5000\n"
1034     "PublishFeatures\t\t5100\n"
1035     "PublishProduct\t\t5200\n"
1036     "InstallFinalize\t\t6000\n";
1037
1038 static const char frp_file_dat[] =
1039     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1040     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1041     "File\tFile\n"
1042     "product.txt\tproduct\tproduct.txt\t1000\t\t\t8192\t1\n";
1043
1044 static const char frp_feature_dat[] =
1045     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1046     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1047     "Feature\tFeature\n"
1048     "product\t\t\tproduct feature\t1\t2\tMSITESTDIR\t0\n";
1049
1050 static const char frp_feature_comp_dat[] =
1051     "Feature_\tComponent_\n"
1052     "s38\ts72\n"
1053     "FeatureComponents\tFeature_\tComponent_\n"
1054     "product\tproduct\n";
1055
1056 static const char frp_component_dat[] =
1057     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1058     "s72\tS38\ts72\ti2\tS255\tS72\n"
1059     "Component\tComponent\n"
1060     "product\t{44725EE0-EEA8-40BD-8162-A48224A2FEA1}\tMSITESTDIR\t0\t\tproduct.txt\n";
1061
1062 static const char frp_custom_action_dat[] =
1063     "Action\tType\tSource\tTarget\tISComments\n"
1064     "s72\ti2\tS64\tS0\tS255\n"
1065     "CustomAction\tAction\n"
1066     "TestProp\t19\t\t\tPROP set\n";
1067
1068 static const char frp_upgrade_dat[] =
1069     "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"
1070     "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"
1071     "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"
1072     "{4C0EAA15-0264-4E5A-8758-609EF142B92D}\t1.1.1\t2.2.2\t\t768\t\tPROP\n";
1073
1074 static const char frp_install_exec_seq_dat[] =
1075     "Action\tCondition\tSequence\n"
1076     "s72\tS255\tI2\n"
1077     "InstallExecuteSequence\tAction\n"
1078     "FindRelatedProducts\t\t50\n"
1079     "TestProp\tPROP AND NOT REMOVE\t51\n"
1080     "LaunchConditions\t\t100\n"
1081     "CostInitialize\t\t800\n"
1082     "FileCost\t\t900\n"
1083     "CostFinalize\t\t1000\n"
1084     "InstallValidate\t\t1400\n"
1085     "InstallInitialize\t\t1500\n"
1086     "ProcessComponents\t\t1600\n"
1087     "RemoveFiles\t\t1700\n"
1088     "InstallFiles\t\t2000\n"
1089     "RegisterProduct\t\t5000\n"
1090     "PublishFeatures\t\t5100\n"
1091     "PublishProduct\t\t5200\n"
1092     "InstallFinalize\t\t6000\n";
1093
1094 static const char riv_file_dat[] =
1095     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1096     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1097     "File\tFile\n"
1098     "inifile.txt\tinifile\tinifile.txt\t1000\t\t\t8192\t1\n";
1099
1100 static const char riv_feature_dat[] =
1101     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1102     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1103     "Feature\tFeature\n"
1104     "inifile\t\t\tinifile feature\t1\t2\tMSITESTDIR\t0\n";
1105
1106 static const char riv_feature_comp_dat[] =
1107     "Feature_\tComponent_\n"
1108     "s38\ts72\n"
1109     "FeatureComponents\tFeature_\tComponent_\n"
1110     "inifile\tinifile\n";
1111
1112 static const char riv_component_dat[] =
1113     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1114     "s72\tS38\ts72\ti2\tS255\tS72\n"
1115     "Component\tComponent\n"
1116     "inifile\t{A0F15705-4F57-4437-88C4-6C8B37ACC6DE}\tMSITESTDIR\t0\t\tinifile.txt\n";
1117
1118 static const char riv_ini_file_dat[] =
1119     "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1120     "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n"
1121     "IniFile\tIniFile\n"
1122     "inifile1\ttest.ini\tMSITESTDIR\tsection1\tkey1\tvalue1\t0\tinifile\n";
1123
1124 static const char riv_remove_ini_file_dat[] =
1125     "RemoveIniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1126     "s72\tl255\tS72\tl96\tl128\tL255\ti2\ts72\n"
1127     "RemoveIniFile\tRemoveIniFile\n"
1128     "inifile1\ttest.ini\tMSITESTDIR\tsectionA\tkeyA\tvalueA\t2\tinifile\n";
1129
1130 static const char riv_install_exec_seq_dat[] =
1131     "Action\tCondition\tSequence\n"
1132     "s72\tS255\tI2\n"
1133     "InstallExecuteSequence\tAction\n"
1134     "LaunchConditions\t\t100\n"
1135     "CostInitialize\t\t800\n"
1136     "FileCost\t\t900\n"
1137     "CostFinalize\t\t1000\n"
1138     "InstallValidate\t\t1400\n"
1139     "InstallInitialize\t\t1500\n"
1140     "ProcessComponents\t\t1600\n"
1141     "RemoveFiles\t\t1700\n"
1142     "InstallFiles\t\t2000\n"
1143     "RemoveIniValues\t\t3000\n"
1144     "RegisterProduct\t\t5000\n"
1145     "PublishFeatures\t\t5100\n"
1146     "PublishProduct\t\t5200\n"
1147     "InstallFinalize\t\t6000\n";
1148
1149 static const char res_file_dat[] =
1150     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1151     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1152     "File\tFile\n"
1153     "envvar.txt\tenvvar\tenvvar.txt\t1000\t\t\t8192\t1\n";
1154
1155 static const char res_feature_dat[] =
1156     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1157     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1158     "Feature\tFeature\n"
1159     "envvar\t\t\tenvvar feature\t1\t2\tMSITESTDIR\t0\n";
1160
1161 static const char res_feature_comp_dat[] =
1162     "Feature_\tComponent_\n"
1163     "s38\ts72\n"
1164     "FeatureComponents\tFeature_\tComponent_\n"
1165     "envvar\tenvvar\n";
1166
1167 static const char res_component_dat[] =
1168     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1169     "s72\tS38\ts72\ti2\tS255\tS72\n"
1170     "Component\tComponent\n"
1171     "envvar\t{45EE9AF4-E5D1-445F-8BB7-B22D4EEBD29E}\tMSITESTDIR\t0\t\tenvvar.txt\n";
1172
1173 static const char res_environment_dat[] =
1174     "Environment\tName\tValue\tComponent_\n"
1175     "s72\tl255\tL255\ts72\n"
1176     "Environment\tEnvironment\n"
1177     "var1\t=-MSITESTVAR1\t1\tenvvar\n"
1178     "var2\t=+-MSITESTVAR2\t1\tenvvar\n"
1179     "var3\t=MSITESTVAR3\t1\tenvvar\n"
1180     "var4\t=-MSITESTVAR4\t\tenvvar\n"
1181     "var5\t=MSITESTVAR5\t\tenvvar\n";
1182
1183 static const char res_install_exec_seq_dat[] =
1184     "Action\tCondition\tSequence\n"
1185     "s72\tS255\tI2\n"
1186     "InstallExecuteSequence\tAction\n"
1187     "LaunchConditions\t\t100\n"
1188     "CostInitialize\t\t800\n"
1189     "FileCost\t\t900\n"
1190     "CostFinalize\t\t1000\n"
1191     "InstallValidate\t\t1400\n"
1192     "InstallInitialize\t\t1500\n"
1193     "ProcessComponents\t\t1600\n"
1194     "RemoveFiles\t\t1700\n"
1195     "InstallFiles\t\t2000\n"
1196     "RemoveEnvironmentStrings\t\t3000\n"
1197     "RegisterProduct\t\t5000\n"
1198     "PublishFeatures\t\t5100\n"
1199     "PublishProduct\t\t5200\n"
1200     "InstallFinalize\t\t6000\n";
1201
1202 static const char rci_file_dat[] =
1203     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1204     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1205     "File\tFile\n"
1206     "class.txt\tclass\tclass.txt\t1000\t\t\t8192\t1\n";
1207
1208 static const char rci_feature_dat[] =
1209     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1210     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1211     "Feature\tFeature\n"
1212     "class\t\t\tclass feature\t1\t2\tMSITESTDIR\t0\n";
1213
1214 static const char rci_feature_comp_dat[] =
1215     "Feature_\tComponent_\n"
1216     "s38\ts72\n"
1217     "FeatureComponents\tFeature_\tComponent_\n"
1218     "class\tclass\n";
1219
1220 static const char rci_component_dat[] =
1221     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1222     "s72\tS38\ts72\ti2\tS255\tS72\n"
1223     "Component\tComponent\n"
1224     "class\t{89A98345-F8A1-422E-A48B-0250B5809F2D}\tMSITESTDIR\t0\t\tclass.txt\n";
1225
1226 static const char rci_appid_dat[] =
1227     "AppId\tRemoteServerName\tLocalService\tServiceParameters\tDllSurrogate\tActivateAtStorage\tRunAsInteractiveUser\n"
1228     "s38\tS255\tS255\tS255\tS255\tI2\tI2\n"
1229     "AppId\tAppId\n"
1230     "{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\t\t\t\t\t\t\n";
1231
1232 static const char rci_class_dat[] =
1233     "CLSID\tContext\tComponent_\tProgId_Default\tDescription\tAppId_\tFileTypeMask\tIcon_\tIconIndex\tDefInprocHandler\tArgument\tFeature_\tAttributes\n"
1234     "s38\ts32\ts72\tS255\tL255\tS38\tS255\tS72\tI2\tS32\tS255\ts38\tI2\n"
1235     "Class\tCLSID\tContext\tComponent_\n"
1236     "{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tLocalServer\tclass\t\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tclass\t\n";
1237
1238 static const char rci_install_exec_seq_dat[] =
1239     "Action\tCondition\tSequence\n"
1240     "s72\tS255\tI2\n"
1241     "InstallExecuteSequence\tAction\n"
1242     "LaunchConditions\t\t100\n"
1243     "CostInitialize\t\t800\n"
1244     "FileCost\t\t900\n"
1245     "CostFinalize\t\t1000\n"
1246     "InstallValidate\t\t1400\n"
1247     "InstallInitialize\t\t1500\n"
1248     "ProcessComponents\t\t1600\n"
1249     "RemoveFiles\t\t1700\n"
1250     "InstallFiles\t\t2000\n"
1251     "UnregisterClassInfo\t\t3000\n"
1252     "RegisterClassInfo\t\t4000\n"
1253     "RegisterProduct\t\t5000\n"
1254     "PublishFeatures\t\t5100\n"
1255     "PublishProduct\t\t5200\n"
1256     "InstallFinalize\t\t6000\n";
1257
1258 static const char rei_file_dat[] =
1259     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1260     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1261     "File\tFile\n"
1262     "extension.txt\textension\textension.txt\t1000\t\t\t8192\t1\n";
1263
1264 static const char rei_feature_dat[] =
1265     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1266     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1267     "Feature\tFeature\n"
1268     "extension\t\t\textension feature\t1\t2\tMSITESTDIR\t0\n";
1269
1270 static const char rei_feature_comp_dat[] =
1271     "Feature_\tComponent_\n"
1272     "s38\ts72\n"
1273     "FeatureComponents\tFeature_\tComponent_\n"
1274     "extension\textension\n";
1275
1276 static const char rei_component_dat[] =
1277     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1278     "s72\tS38\ts72\ti2\tS255\tS72\n"
1279     "Component\tComponent\n"
1280     "extension\t{9A3060D4-60BA-4A82-AB55-9FB148AD013C}\tMSITESTDIR\t0\t\textension.txt\n";
1281
1282 static const char rei_extension_dat[] =
1283     "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1284     "s255\ts72\tS255\tS64\ts38\n"
1285     "Extension\tExtension\tComponent_\n"
1286     "extension\textension\tProg.Id.1\t\textension\n";
1287
1288 static const char rei_verb_dat[] =
1289     "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1290     "s255\ts32\tI2\tL255\tL255\n"
1291     "Verb\tExtension_\tVerb\n"
1292     "extension\tOpen\t1\t&Open\t/argument\n";
1293
1294 static const char rei_progid_dat[] =
1295     "ProgId\tProgId_Parent\tClass_\tDescription\tIcon_\tIconIndex\n"
1296     "s255\tS255\tS38\tL255\tS72\tI2\n"
1297     "ProgId\tProgId\n"
1298     "Prog.Id.1\t\t\tdescription\t\t\n";
1299
1300 static const char rei_install_exec_seq_dat[] =
1301     "Action\tCondition\tSequence\n"
1302     "s72\tS255\tI2\n"
1303     "InstallExecuteSequence\tAction\n"
1304     "LaunchConditions\t\t100\n"
1305     "CostInitialize\t\t800\n"
1306     "FileCost\t\t900\n"
1307     "CostFinalize\t\t1000\n"
1308     "InstallValidate\t\t1400\n"
1309     "InstallInitialize\t\t1500\n"
1310     "ProcessComponents\t\t1600\n"
1311     "RemoveFiles\t\t1700\n"
1312     "InstallFiles\t\t2000\n"
1313     "UnregisterExtensionInfo\t\t3000\n"
1314     "RegisterExtensionInfo\t\t4000\n"
1315     "RegisterProduct\t\t5000\n"
1316     "PublishFeatures\t\t5100\n"
1317     "PublishProduct\t\t5200\n"
1318     "InstallFinalize\t\t6000\n";
1319
1320 static const char rmi_file_dat[] =
1321     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1322     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1323     "File\tFile\n"
1324     "mime.txt\tmime\tmime.txt\t1000\t\t\t8192\t1\n";
1325
1326 static const char rmi_feature_dat[] =
1327     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1328     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1329     "Feature\tFeature\n"
1330     "mime\t\t\tmime feature\t1\t2\tMSITESTDIR\t0\n";
1331
1332 static const char rmi_feature_comp_dat[] =
1333     "Feature_\tComponent_\n"
1334     "s38\ts72\n"
1335     "FeatureComponents\tFeature_\tComponent_\n"
1336     "mime\tmime\n";
1337
1338 static const char rmi_component_dat[] =
1339     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1340     "s72\tS38\ts72\ti2\tS255\tS72\n"
1341     "Component\tComponent\n"
1342     "mime\t{A1D630CE-13A7-4882-AFDD-148E2BBAFC6D}\tMSITESTDIR\t0\t\tmime.txt\n";
1343
1344 static const char rmi_extension_dat[] =
1345     "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1346     "s255\ts72\tS255\tS64\ts38\n"
1347     "Extension\tExtension\tComponent_\n"
1348     "mime\tmime\t\tmime/type\tmime\n";
1349
1350 static const char rmi_verb_dat[] =
1351     "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1352     "s255\ts32\tI2\tL255\tL255\n"
1353     "Verb\tExtension_\tVerb\n"
1354     "mime\tOpen\t1\t&Open\t/argument\n";
1355
1356 static const char rmi_mime_dat[] =
1357     "ContentType\tExtension_\tCLSID\n"
1358     "s64\ts255\tS38\n"
1359     "MIME\tContentType\n"
1360     "mime/type\tmime\t\n";
1361
1362 static const char rmi_install_exec_seq_dat[] =
1363     "Action\tCondition\tSequence\n"
1364     "s72\tS255\tI2\n"
1365     "InstallExecuteSequence\tAction\n"
1366     "LaunchConditions\t\t100\n"
1367     "CostInitialize\t\t800\n"
1368     "FileCost\t\t900\n"
1369     "CostFinalize\t\t1000\n"
1370     "InstallValidate\t\t1400\n"
1371     "InstallInitialize\t\t1500\n"
1372     "ProcessComponents\t\t1600\n"
1373     "RemoveFiles\t\t1700\n"
1374     "InstallFiles\t\t2000\n"
1375     "UnregisterExtensionInfo\t\t3000\n"
1376     "UnregisterMIMEInfo\t\t3500\n"
1377     "RegisterExtensionInfo\t\t4000\n"
1378     "RegisterMIMEInfo\t\t4500\n"
1379     "RegisterProduct\t\t5000\n"
1380     "PublishFeatures\t\t5100\n"
1381     "PublishProduct\t\t5200\n"
1382     "InstallFinalize\t\t6000\n";
1383
1384 static const char pa_file_dat[] =
1385     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1386     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1387     "File\tFile\n"
1388     "win32.txt\twin32\twin32.txt\t1000\t\t\t8192\t1\n"
1389     "manifest.txt\twin32\tmanifest.txt\t1000\t\t\t8192\t1\n"
1390     "win32_local.txt\twin32_local\twin32_local.txt\t1000\t\t\t8192\t1\n"
1391     "manifest_local.txt\twin32_local\tmanifest_local.txt\t1000\t\t\t8192\t1\n"
1392     "dotnet.txt\tdotnet\tdotnet.txt\t1000\t\t\t8192\t1\n"
1393     "dotnet_local.txt\tdotnet_local\tdotnet_local.txt\t1000\t\t\t8192\t1\n"
1394     "application_win32.txt\twin32_local\tapplication_win32.txt\t1000\t\t\t8192\t1\n"
1395     "application_dotnet.txt\tdotnet_local\tapplication_dotnet.txt\t1000\t\t\t8192\t1\n";
1396
1397 static const char pa_feature_dat[] =
1398     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1399     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1400     "Feature\tFeature\n"
1401     "assembly\t\t\tassembly feature\t1\t2\tMSITESTDIR\t0\n";
1402
1403 static const char pa_feature_comp_dat[] =
1404     "Feature_\tComponent_\n"
1405     "s38\ts72\n"
1406     "FeatureComponents\tFeature_\tComponent_\n"
1407     "assembly\twin32\n"
1408     "assembly\twin32_local\n"
1409     "assembly\tdotnet\n"
1410     "assembly\tdotnet_local\n";
1411
1412 static const char pa_component_dat[] =
1413     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1414     "s72\tS38\ts72\ti2\tS255\tS72\n"
1415     "Component\tComponent\n"
1416     "win32\t{F515549E-7E61-425D-AAC1-9BEF2E066D06}\tMSITESTDIR\t0\t\twin32.txt\n"
1417     "win32_local\t{D34D3FBA-6789-4E57-AD1A-1281297DC201}\tMSITESTDIR\t0\t\twin32_local.txt\n"
1418     "dotnet\t{8943164F-2B31-4C09-A894-493A8CBDE0A4}\tMSITESTDIR\t0\t\tdotnet.txt\n"
1419     "dotnet_local\t{4E8567E8-8EAE-4E36-90F1-B99D33C663F8}\tMSITESTDIR\t0\t\tdotnet_local.txt\n";
1420
1421 static const char pa_msi_assembly_dat[] =
1422     "Component_\tFeature_\tFile_Manifest\tFile_Application\tAttributes\n"
1423     "s72\ts38\tS72\tS72\tI2\n"
1424     "MsiAssembly\tComponent_\n"
1425     "win32\tassembly\tmanifest.txt\t\t1\n"
1426     "win32_local\tassembly\tmanifest_local.txt\tapplication_win32.txt\t1\n"
1427     "dotnet\tassembly\t\t\t0\n"
1428     "dotnet_local\tassembly\t\tapplication_dotnet.txt\t0\n";
1429
1430 static const char pa_msi_assembly_name_dat[] =
1431     "Component_\tName\tValue\n"
1432     "s72\ts255\ts255\n"
1433     "MsiAssemblyName\tComponent_\tName\n"
1434     "win32\tName\tWine.Win32.Assembly\n"
1435     "win32\tprocessorArchitecture\tx86\n"
1436     "win32\tpublicKeyToken\tabcdef0123456789\n"
1437     "win32\ttype\twin32\n"
1438     "win32\tversion\t1.0.0.0\n"
1439     "win32_local\tName\tWine.Win32.Local.Assembly\n"
1440     "win32_local\tprocessorArchitecture\tx86\n"
1441     "win32_local\tpublicKeyToken\tabcdef0123456789\n"
1442     "win32_local\ttype\twin32\n"
1443     "win32_local\tversion\t1.0.0.0\n"
1444     "dotnet\tName\tWine.Dotnet.Assembly\n"
1445     "dotnet\tprocessorArchitecture\tMSIL\n"
1446     "dotnet\tpublicKeyToken\tabcdef0123456789\n"
1447     "dotnet\tculture\tneutral\n"
1448     "dotnet\tversion\t1.0.0.0\n"
1449     "dotnet_local\tName\tWine.Dotnet.Local.Assembly\n"
1450     "dotnet_local\tprocessorArchitecture\tMSIL\n"
1451     "dotnet_local\tpublicKeyToken\tabcdef0123456789\n"
1452     "dotnet_local\tculture\tneutral\n"
1453     "dotnet_local\tversion\t1.0.0.0\n";
1454
1455 static const char pa_install_exec_seq_dat[] =
1456     "Action\tCondition\tSequence\n"
1457     "s72\tS255\tI2\n"
1458     "InstallExecuteSequence\tAction\n"
1459     "LaunchConditions\t\t100\n"
1460     "CostInitialize\t\t800\n"
1461     "FileCost\t\t900\n"
1462     "CostFinalize\t\t1000\n"
1463     "InstallValidate\t\t1400\n"
1464     "InstallInitialize\t\t1500\n"
1465     "ProcessComponents\t\t1600\n"
1466     "MsiPublishAssemblies\t\t3000\n"
1467     "MsiUnpublishAssemblies\t\t4000\n"
1468     "RegisterProduct\t\t5000\n"
1469     "PublishFeatures\t\t5100\n"
1470     "PublishProduct\t\t5200\n"
1471     "InstallFinalize\t\t6000\n";
1472
1473 static const char rep_file_dat[] =
1474     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1475     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1476     "File\tFile\n"
1477     "rep.txt\trep\trep.txt\t1000\t\t\t8192\t1\n";
1478
1479 static const char rep_feature_dat[] =
1480     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1481     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1482     "Feature\tFeature\n"
1483     "rep\t\t\trep feature\t1\t2\tMSITESTDIR\t0\n";
1484
1485 static const char rep_feature_comp_dat[] =
1486     "Feature_\tComponent_\n"
1487     "s38\ts72\n"
1488     "FeatureComponents\tFeature_\tComponent_\n"
1489     "rep\trep\n";
1490
1491 static const char rep_component_dat[] =
1492     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1493     "s72\tS38\ts72\ti2\tS255\tS72\n"
1494     "Component\tComponent\n"
1495     "rep\t{A24FAF2A-3B2E-41EF-AA78-331542E1A29D}\tMSITESTDIR\t0\t\trep.txt\n";
1496
1497 static const char rep_upgrade_dat[] =
1498     "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"
1499     "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"
1500     "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"
1501     "{2967C1CC-34D4-42EE-8D96-CD6836F192BF}\t\t\t\t256\t\tPRODUCT\n";
1502
1503 static const char rep_property_dat[] =
1504     "Property\tValue\n"
1505     "s72\tl0\n"
1506     "Property\tProperty\n"
1507     "HASUIRUN\t0\n"
1508     "INSTALLLEVEL\t3\n"
1509     "InstallMode\tTypical\n"
1510     "Manufacturer\tWine\n"
1511     "PIDTemplate\t###-#######\n"
1512     "ProductCode\t{1699F0BB-0B61-4A89-AFE4-CFD60DFD76F3}\n"
1513     "ProductLanguage\t1033\n"
1514     "ProductName\tMSITEST\n"
1515     "ProductVersion\t1.1.1\n"
1516     "UpgradeCode\t{2967C1CC-34D4-42EE-8D96-CD6836F192BF}\n"
1517     "PRODUCT\t2F41860D-7B4C-4DA7-BED9-B64F26594C56\n"
1518     "MSIFASTINSTALL\t1\n";
1519
1520 static const char rep_install_exec_seq_dat[] =
1521     "Action\tCondition\tSequence\n"
1522     "s72\tS255\tI2\n"
1523     "InstallExecuteSequence\tAction\n"
1524     "FindRelatedProducts\t\t100\n"
1525     "CostInitialize\t\t800\n"
1526     "FileCost\t\t900\n"
1527     "CostFinalize\t\t1000\n"
1528     "InstallValidate\t\t1400\n"
1529     "RemoveExistingProducts\t\t1499\n"
1530     "InstallInitialize\t\t1500\n"
1531     "ProcessComponents\t\t1600\n"
1532     "RemoveFiles\t\t1700\n"
1533     "InstallFiles\t\t2000\n"
1534     "UnregisterExtensionInfo\t\t3000\n"
1535     "UnregisterMIMEInfo\t\t3500\n"
1536     "RegisterExtensionInfo\t\t4000\n"
1537     "RegisterMIMEInfo\t\t4500\n"
1538     "RegisterProduct\t\t5000\n"
1539     "PublishFeatures\t\t5100\n"
1540     "PublishProduct\t\t5200\n"
1541     "InstallFinalize\t\t6000\n";
1542
1543 typedef struct _msi_table
1544 {
1545     const char *filename;
1546     const char *data;
1547     unsigned int size;
1548 } msi_table;
1549
1550 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
1551
1552 static const msi_table env_tables[] =
1553 {
1554     ADD_TABLE(component),
1555     ADD_TABLE(directory),
1556     ADD_TABLE(feature),
1557     ADD_TABLE(feature_comp),
1558     ADD_TABLE(file),
1559     ADD_TABLE(install_exec_seq),
1560     ADD_TABLE(media),
1561     ADD_TABLE(property),
1562     ADD_TABLE(environment)
1563 };
1564
1565 static const msi_table pp_tables[] =
1566 {
1567     ADD_TABLE(pp_component),
1568     ADD_TABLE(directory),
1569     ADD_TABLE(rof_feature),
1570     ADD_TABLE(rof_feature_comp),
1571     ADD_TABLE(rof_file),
1572     ADD_TABLE(pp_install_exec_seq),
1573     ADD_TABLE(rof_media),
1574     ADD_TABLE(property),
1575 };
1576
1577 static const msi_table ppc_tables[] =
1578 {
1579     ADD_TABLE(ppc_component),
1580     ADD_TABLE(directory),
1581     ADD_TABLE(rof_feature),
1582     ADD_TABLE(ppc_feature_comp),
1583     ADD_TABLE(ppc_file),
1584     ADD_TABLE(pp_install_exec_seq),
1585     ADD_TABLE(ppc_media),
1586     ADD_TABLE(property),
1587 };
1588
1589 static const msi_table rem_tables[] =
1590 {
1591     ADD_TABLE(rem_component),
1592     ADD_TABLE(directory),
1593     ADD_TABLE(rof_feature),
1594     ADD_TABLE(rem_feature_comp),
1595     ADD_TABLE(rem_file),
1596     ADD_TABLE(rem_install_exec_seq),
1597     ADD_TABLE(rof_media),
1598     ADD_TABLE(property),
1599     ADD_TABLE(rem_remove_files),
1600 };
1601
1602 static const msi_table mov_tables[] =
1603 {
1604     ADD_TABLE(cwd_component),
1605     ADD_TABLE(directory),
1606     ADD_TABLE(rof_feature),
1607     ADD_TABLE(ci2_feature_comp),
1608     ADD_TABLE(ci2_file),
1609     ADD_TABLE(install_exec_seq),
1610     ADD_TABLE(rof_media),
1611     ADD_TABLE(property),
1612     ADD_TABLE(mov_move_file),
1613 };
1614
1615 static const msi_table df_tables[] =
1616 {
1617     ADD_TABLE(rof_component),
1618     ADD_TABLE(df_directory),
1619     ADD_TABLE(rof_feature),
1620     ADD_TABLE(rof_feature_comp),
1621     ADD_TABLE(rof_file),
1622     ADD_TABLE(install_exec_seq),
1623     ADD_TABLE(rof_media),
1624     ADD_TABLE(property),
1625     ADD_TABLE(df_duplicate_file),
1626 };
1627
1628 static const msi_table wrv_tables[] =
1629 {
1630     ADD_TABLE(wrv_component),
1631     ADD_TABLE(directory),
1632     ADD_TABLE(rof_feature),
1633     ADD_TABLE(ci2_feature_comp),
1634     ADD_TABLE(ci2_file),
1635     ADD_TABLE(install_exec_seq),
1636     ADD_TABLE(rof_media),
1637     ADD_TABLE(property),
1638     ADD_TABLE(wrv_registry),
1639 };
1640
1641 static const msi_table cf_tables[] =
1642 {
1643     ADD_TABLE(cf_component),
1644     ADD_TABLE(cf_directory),
1645     ADD_TABLE(cf_feature),
1646     ADD_TABLE(cf_feature_comp),
1647     ADD_TABLE(cf_file),
1648     ADD_TABLE(cf_create_folders),
1649     ADD_TABLE(cf_install_exec_seq),
1650     ADD_TABLE(media),
1651     ADD_TABLE(property)
1652 };
1653
1654 static const msi_table sss_tables[] =
1655 {
1656     ADD_TABLE(component),
1657     ADD_TABLE(directory),
1658     ADD_TABLE(feature),
1659     ADD_TABLE(feature_comp),
1660     ADD_TABLE(file),
1661     ADD_TABLE(sss_install_exec_seq),
1662     ADD_TABLE(sss_service_control),
1663     ADD_TABLE(media),
1664     ADD_TABLE(property)
1665 };
1666
1667 static const msi_table sds_tables[] =
1668 {
1669     ADD_TABLE(component),
1670     ADD_TABLE(directory),
1671     ADD_TABLE(feature),
1672     ADD_TABLE(feature_comp),
1673     ADD_TABLE(file),
1674     ADD_TABLE(sds_install_exec_seq),
1675     ADD_TABLE(service_control),
1676     ADD_TABLE(service_install),
1677     ADD_TABLE(media),
1678     ADD_TABLE(property)
1679 };
1680
1681 static const msi_table sr_tables[] =
1682 {
1683     ADD_TABLE(component),
1684     ADD_TABLE(directory),
1685     ADD_TABLE(feature),
1686     ADD_TABLE(feature_comp),
1687     ADD_TABLE(file),
1688     ADD_TABLE(sr_selfreg),
1689     ADD_TABLE(sr_install_exec_seq),
1690     ADD_TABLE(media),
1691     ADD_TABLE(property)
1692 };
1693
1694 static const msi_table font_tables[] =
1695 {
1696     ADD_TABLE(font_component),
1697     ADD_TABLE(directory),
1698     ADD_TABLE(font_feature),
1699     ADD_TABLE(font_feature_comp),
1700     ADD_TABLE(font_file),
1701     ADD_TABLE(font),
1702     ADD_TABLE(font_install_exec_seq),
1703     ADD_TABLE(font_media),
1704     ADD_TABLE(property)
1705 };
1706
1707 static const msi_table vp_tables[] =
1708 {
1709     ADD_TABLE(component),
1710     ADD_TABLE(directory),
1711     ADD_TABLE(feature),
1712     ADD_TABLE(feature_comp),
1713     ADD_TABLE(file),
1714     ADD_TABLE(vp_custom_action),
1715     ADD_TABLE(vp_install_exec_seq),
1716     ADD_TABLE(media),
1717     ADD_TABLE(vp_property)
1718 };
1719
1720 static const msi_table odbc_tables[] =
1721 {
1722     ADD_TABLE(odbc_component),
1723     ADD_TABLE(directory),
1724     ADD_TABLE(odbc_feature),
1725     ADD_TABLE(odbc_feature_comp),
1726     ADD_TABLE(odbc_file),
1727     ADD_TABLE(odbc_driver),
1728     ADD_TABLE(odbc_translator),
1729     ADD_TABLE(odbc_datasource),
1730     ADD_TABLE(odbc_install_exec_seq),
1731     ADD_TABLE(odbc_media),
1732     ADD_TABLE(property)
1733 };
1734
1735 static const msi_table tl_tables[] =
1736 {
1737     ADD_TABLE(tl_component),
1738     ADD_TABLE(directory),
1739     ADD_TABLE(tl_feature),
1740     ADD_TABLE(tl_feature_comp),
1741     ADD_TABLE(tl_file),
1742     ADD_TABLE(tl_typelib),
1743     ADD_TABLE(tl_install_exec_seq),
1744     ADD_TABLE(media),
1745     ADD_TABLE(property)
1746 };
1747
1748 static const msi_table crs_tables[] =
1749 {
1750     ADD_TABLE(crs_component),
1751     ADD_TABLE(directory),
1752     ADD_TABLE(crs_feature),
1753     ADD_TABLE(crs_feature_comp),
1754     ADD_TABLE(crs_file),
1755     ADD_TABLE(crs_shortcut),
1756     ADD_TABLE(crs_install_exec_seq),
1757     ADD_TABLE(media),
1758     ADD_TABLE(property)
1759 };
1760
1761 static const msi_table pub_tables[] =
1762 {
1763     ADD_TABLE(directory),
1764     ADD_TABLE(pub_component),
1765     ADD_TABLE(pub_feature),
1766     ADD_TABLE(pub_feature_comp),
1767     ADD_TABLE(pub_file),
1768     ADD_TABLE(pub_publish_component),
1769     ADD_TABLE(pub_install_exec_seq),
1770     ADD_TABLE(media),
1771     ADD_TABLE(property)
1772 };
1773
1774 static const msi_table rd_tables[] =
1775 {
1776     ADD_TABLE(directory),
1777     ADD_TABLE(rd_component),
1778     ADD_TABLE(rd_feature),
1779     ADD_TABLE(rd_feature_comp),
1780     ADD_TABLE(rd_file),
1781     ADD_TABLE(rd_duplicate_file),
1782     ADD_TABLE(rd_install_exec_seq),
1783     ADD_TABLE(media),
1784     ADD_TABLE(property)
1785 };
1786
1787 static const msi_table rrv_tables[] =
1788 {
1789     ADD_TABLE(directory),
1790     ADD_TABLE(rrv_component),
1791     ADD_TABLE(rrv_feature),
1792     ADD_TABLE(rrv_feature_comp),
1793     ADD_TABLE(rrv_file),
1794     ADD_TABLE(rrv_registry),
1795     ADD_TABLE(rrv_remove_registry),
1796     ADD_TABLE(rrv_install_exec_seq),
1797     ADD_TABLE(media),
1798     ADD_TABLE(property)
1799 };
1800
1801 static const msi_table frp_tables[] =
1802 {
1803     ADD_TABLE(directory),
1804     ADD_TABLE(frp_component),
1805     ADD_TABLE(frp_feature),
1806     ADD_TABLE(frp_feature_comp),
1807     ADD_TABLE(frp_file),
1808     ADD_TABLE(frp_upgrade),
1809     ADD_TABLE(frp_custom_action),
1810     ADD_TABLE(frp_install_exec_seq),
1811     ADD_TABLE(media),
1812     ADD_TABLE(property)
1813 };
1814
1815 static const msi_table riv_tables[] =
1816 {
1817     ADD_TABLE(directory),
1818     ADD_TABLE(riv_component),
1819     ADD_TABLE(riv_feature),
1820     ADD_TABLE(riv_feature_comp),
1821     ADD_TABLE(riv_file),
1822     ADD_TABLE(riv_ini_file),
1823     ADD_TABLE(riv_remove_ini_file),
1824     ADD_TABLE(riv_install_exec_seq),
1825     ADD_TABLE(media),
1826     ADD_TABLE(property)
1827 };
1828
1829 static const msi_table res_tables[] =
1830 {
1831     ADD_TABLE(directory),
1832     ADD_TABLE(res_component),
1833     ADD_TABLE(res_feature),
1834     ADD_TABLE(res_feature_comp),
1835     ADD_TABLE(res_file),
1836     ADD_TABLE(res_environment),
1837     ADD_TABLE(res_install_exec_seq),
1838     ADD_TABLE(media),
1839     ADD_TABLE(property)
1840 };
1841
1842 static const msi_table rci_tables[] =
1843 {
1844     ADD_TABLE(directory),
1845     ADD_TABLE(rci_component),
1846     ADD_TABLE(rci_feature),
1847     ADD_TABLE(rci_feature_comp),
1848     ADD_TABLE(rci_file),
1849     ADD_TABLE(rci_appid),
1850     ADD_TABLE(rci_class),
1851     ADD_TABLE(rci_install_exec_seq),
1852     ADD_TABLE(media),
1853     ADD_TABLE(property)
1854 };
1855
1856 static const msi_table rei_tables[] =
1857 {
1858     ADD_TABLE(directory),
1859     ADD_TABLE(rei_component),
1860     ADD_TABLE(rei_feature),
1861     ADD_TABLE(rei_feature_comp),
1862     ADD_TABLE(rei_file),
1863     ADD_TABLE(rei_extension),
1864     ADD_TABLE(rei_verb),
1865     ADD_TABLE(rei_progid),
1866     ADD_TABLE(rei_install_exec_seq),
1867     ADD_TABLE(media),
1868     ADD_TABLE(property)
1869 };
1870
1871 static const msi_table rmi_tables[] =
1872 {
1873     ADD_TABLE(directory),
1874     ADD_TABLE(rmi_component),
1875     ADD_TABLE(rmi_feature),
1876     ADD_TABLE(rmi_feature_comp),
1877     ADD_TABLE(rmi_file),
1878     ADD_TABLE(rmi_extension),
1879     ADD_TABLE(rmi_verb),
1880     ADD_TABLE(rmi_mime),
1881     ADD_TABLE(rmi_install_exec_seq),
1882     ADD_TABLE(media),
1883     ADD_TABLE(property)
1884 };
1885
1886 static const msi_table pa_tables[] =
1887 {
1888     ADD_TABLE(directory),
1889     ADD_TABLE(pa_component),
1890     ADD_TABLE(pa_feature),
1891     ADD_TABLE(pa_feature_comp),
1892     ADD_TABLE(pa_file),
1893     ADD_TABLE(pa_msi_assembly),
1894     ADD_TABLE(pa_msi_assembly_name),
1895     ADD_TABLE(pa_install_exec_seq),
1896     ADD_TABLE(media),
1897     ADD_TABLE(property)
1898 };
1899
1900 static const msi_table rep_tables[] =
1901 {
1902     ADD_TABLE(directory),
1903     ADD_TABLE(rep_component),
1904     ADD_TABLE(rep_feature),
1905     ADD_TABLE(rep_feature_comp),
1906     ADD_TABLE(rep_file),
1907     ADD_TABLE(rep_upgrade),
1908     ADD_TABLE(rep_property),
1909     ADD_TABLE(rep_install_exec_seq),
1910     ADD_TABLE(media)
1911 };
1912
1913 /* based on RegDeleteTreeW from dlls/advapi32/registry.c */
1914 static LSTATUS action_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey, REGSAM access)
1915 {
1916     LONG ret;
1917     DWORD dwMaxSubkeyLen, dwMaxValueLen;
1918     DWORD dwMaxLen, dwSize;
1919     char szNameBuf[MAX_PATH], *lpszName = szNameBuf;
1920     HKEY hSubKey = hKey;
1921
1922     if(lpszSubKey)
1923     {
1924         ret = RegOpenKeyExA(hKey, lpszSubKey, 0, access, &hSubKey);
1925         if (ret) return ret;
1926     }
1927
1928     ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL,
1929             &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
1930     if (ret) goto cleanup;
1931
1932     dwMaxSubkeyLen++;
1933     dwMaxValueLen++;
1934     dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
1935     if (dwMaxLen > sizeof(szNameBuf))
1936     {
1937         /* Name too big: alloc a buffer for it */
1938         if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen)))
1939         {
1940             ret = ERROR_NOT_ENOUGH_MEMORY;
1941             goto cleanup;
1942         }
1943     }
1944
1945     /* Recursively delete all the subkeys */
1946     while (TRUE)
1947     {
1948         dwSize = dwMaxLen;
1949         if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL,
1950                           NULL, NULL, NULL)) break;
1951
1952         ret = action_RegDeleteTreeA(hSubKey, lpszName, access);
1953         if (ret) goto cleanup;
1954     }
1955
1956     if (lpszSubKey)
1957     {
1958         if (pRegDeleteKeyExA)
1959             ret = pRegDeleteKeyExA(hKey, lpszSubKey, access, 0);
1960         else
1961             ret = RegDeleteKeyA(hKey, lpszSubKey);
1962     }
1963     else
1964         while (TRUE)
1965         {
1966             dwSize = dwMaxLen;
1967             if (RegEnumValueA(hKey, 0, lpszName, &dwSize,
1968                   NULL, NULL, NULL, NULL)) break;
1969
1970             ret = RegDeleteValueA(hKey, lpszName);
1971             if (ret) goto cleanup;
1972         }
1973
1974 cleanup:
1975     if (lpszName != szNameBuf)
1976         HeapFree(GetProcessHeap(), 0, lpszName);
1977     if(lpszSubKey)
1978         RegCloseKey(hSubKey);
1979     return ret;
1980 }
1981
1982 /* cabinet definitions */
1983
1984 /* make the max size large so there is only one cab file */
1985 #define MEDIA_SIZE          0x7FFFFFFF
1986 #define FOLDER_THRESHOLD    900000
1987
1988 /* the FCI callbacks */
1989
1990 static void * CDECL mem_alloc(ULONG cb)
1991 {
1992     return HeapAlloc(GetProcessHeap(), 0, cb);
1993 }
1994
1995 static void CDECL mem_free(void *memory)
1996 {
1997     HeapFree(GetProcessHeap(), 0, memory);
1998 }
1999
2000 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
2001 {
2002     sprintf(pccab->szCab, pv, pccab->iCab);
2003     return TRUE;
2004 }
2005
2006 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
2007 {
2008     return 0;
2009 }
2010
2011 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
2012                              BOOL fContinuation, void *pv)
2013 {
2014     return 0;
2015 }
2016
2017 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
2018 {
2019     HANDLE handle;
2020     DWORD dwAccess = 0;
2021     DWORD dwShareMode = 0;
2022     DWORD dwCreateDisposition = OPEN_EXISTING;
2023
2024     dwAccess = GENERIC_READ | GENERIC_WRITE;
2025     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
2026
2027     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
2028         dwCreateDisposition = OPEN_EXISTING;
2029     else
2030         dwCreateDisposition = CREATE_NEW;
2031
2032     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
2033                          dwCreateDisposition, 0, NULL);
2034
2035     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
2036
2037     return (INT_PTR)handle;
2038 }
2039
2040 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2041 {
2042     HANDLE handle = (HANDLE)hf;
2043     DWORD dwRead;
2044     BOOL res;
2045
2046     res = ReadFile(handle, memory, cb, &dwRead, NULL);
2047     ok(res, "Failed to ReadFile\n");
2048
2049     return dwRead;
2050 }
2051
2052 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2053 {
2054     HANDLE handle = (HANDLE)hf;
2055     DWORD dwWritten;
2056     BOOL res;
2057
2058     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
2059     ok(res, "Failed to WriteFile\n");
2060
2061     return dwWritten;
2062 }
2063
2064 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
2065 {
2066     HANDLE handle = (HANDLE)hf;
2067     ok(CloseHandle(handle), "Failed to CloseHandle\n");
2068
2069     return 0;
2070 }
2071
2072 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
2073 {
2074     HANDLE handle = (HANDLE)hf;
2075     DWORD ret;
2076
2077     ret = SetFilePointer(handle, dist, NULL, seektype);
2078     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
2079
2080     return ret;
2081 }
2082
2083 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
2084 {
2085     BOOL ret = DeleteFileA(pszFile);
2086     ok(ret, "Failed to DeleteFile %s\n", pszFile);
2087
2088     return 0;
2089 }
2090
2091 static void init_functionpointers(void)
2092 {
2093     HMODULE hmsi = GetModuleHandleA("msi.dll");
2094     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
2095     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
2096
2097 #define GET_PROC(mod, func) \
2098     p ## func = (void*)GetProcAddress(mod, #func); \
2099     if(!p ## func) \
2100       trace("GetProcAddress(%s) failed\n", #func);
2101
2102     GET_PROC(hmsi, MsiQueryComponentStateA);
2103     GET_PROC(hmsi, MsiSourceListEnumSourcesA);
2104     GET_PROC(hmsi, MsiSourceListGetInfoA);
2105     GET_PROC(hmsi, MsiGetComponentPathExA);
2106     GET_PROC(hmsi, MsiQueryFeatureStateExA);
2107
2108     GET_PROC(hadvapi32, ConvertSidToStringSidA);
2109     GET_PROC(hadvapi32, OpenProcessToken);
2110     GET_PROC(hadvapi32, RegDeleteKeyExA)
2111     GET_PROC(hkernel32, IsWow64Process)
2112
2113     hsrclient = LoadLibraryA("srclient.dll");
2114     GET_PROC(hsrclient, SRRemoveRestorePoint);
2115     GET_PROC(hsrclient, SRSetRestorePointA);
2116
2117 #undef GET_PROC
2118 }
2119
2120 static BOOL is_process_limited(void)
2121 {
2122     HANDLE token;
2123
2124     if (!pOpenProcessToken) return FALSE;
2125
2126     if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
2127     {
2128         BOOL ret;
2129         TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
2130         DWORD size;
2131
2132         ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
2133         CloseHandle(token);
2134         return (ret && type == TokenElevationTypeLimited);
2135     }
2136     return FALSE;
2137 }
2138
2139 static char *get_user_sid(void)
2140 {
2141     HANDLE token;
2142     DWORD size = 0;
2143     TOKEN_USER *user;
2144     char *usersid = NULL;
2145
2146     if (!pConvertSidToStringSidA)
2147     {
2148         win_skip("ConvertSidToStringSidA is not available\n");
2149         return NULL;
2150     }
2151     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
2152     GetTokenInformation(token, TokenUser, NULL, size, &size);
2153
2154     user = HeapAlloc(GetProcessHeap(), 0, size);
2155     GetTokenInformation(token, TokenUser, user, size, &size);
2156     pConvertSidToStringSidA(user->User.Sid, &usersid);
2157     HeapFree(GetProcessHeap(), 0, user);
2158
2159     CloseHandle(token);
2160     return usersid;
2161 }
2162
2163 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
2164 {
2165     LPSTR tempname;
2166
2167     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2168     GetTempFileNameA(".", "xx", 0, tempname);
2169
2170     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
2171     {
2172         lstrcpyA(pszTempName, tempname);
2173         HeapFree(GetProcessHeap(), 0, tempname);
2174         return TRUE;
2175     }
2176
2177     HeapFree(GetProcessHeap(), 0, tempname);
2178
2179     return FALSE;
2180 }
2181
2182 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
2183                                    USHORT *pattribs, int *err, void *pv)
2184 {
2185     BY_HANDLE_FILE_INFORMATION finfo;
2186     FILETIME filetime;
2187     HANDLE handle;
2188     DWORD attrs;
2189     BOOL res;
2190
2191     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
2192                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
2193
2194     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
2195
2196     res = GetFileInformationByHandle(handle, &finfo);
2197     ok(res, "Expected GetFileInformationByHandle to succeed\n");
2198
2199     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
2200     FileTimeToDosDateTime(&filetime, pdate, ptime);
2201
2202     attrs = GetFileAttributes(pszName);
2203     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
2204
2205     return (INT_PTR)handle;
2206 }
2207
2208 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
2209 {
2210     char path[MAX_PATH];
2211     char filename[MAX_PATH];
2212
2213     lstrcpyA(path, CURR_DIR);
2214     lstrcatA(path, "\\");
2215     lstrcatA(path, file);
2216
2217     lstrcpyA(filename, file);
2218
2219     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
2220                       progress, get_open_info, compress);
2221 }
2222
2223 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
2224 {
2225     ZeroMemory(pCabParams, sizeof(CCAB));
2226
2227     pCabParams->cb = max_size;
2228     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
2229     pCabParams->setID = 0xbeef;
2230     pCabParams->iCab = 1;
2231     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
2232     lstrcatA(pCabParams->szCabPath, "\\");
2233     lstrcpyA(pCabParams->szCab, name);
2234 }
2235
2236 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
2237 {
2238     CCAB cabParams;
2239     LPCSTR ptr;
2240     HFCI hfci;
2241     ERF erf;
2242     BOOL res;
2243
2244     set_cab_parameters(&cabParams, name, max_size);
2245
2246     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
2247                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
2248                       get_temp_file, &cabParams, NULL);
2249
2250     ok(hfci != NULL, "Failed to create an FCI context\n");
2251
2252     ptr = files;
2253     while (*ptr)
2254     {
2255         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
2256         ok(res, "Failed to add file: %s\n", ptr);
2257         ptr += lstrlen(ptr) + 1;
2258     }
2259
2260     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
2261     ok(res, "Failed to flush the cabinet\n");
2262
2263     res = FCIDestroy(hfci);
2264     ok(res, "Failed to destroy the cabinet\n");
2265 }
2266
2267 static BOOL get_user_dirs(void)
2268 {
2269     HKEY hkey;
2270     DWORD type, size;
2271
2272     if (RegOpenKey(HKEY_CURRENT_USER,
2273                    "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hkey))
2274         return FALSE;
2275
2276     size = MAX_PATH;
2277     if (RegQueryValueExA(hkey, "AppData", 0, &type, (LPBYTE)APP_DATA_DIR, &size))
2278     {
2279         RegCloseKey(hkey);
2280         return FALSE;
2281     }
2282
2283     RegCloseKey(hkey);
2284     return TRUE;
2285 }
2286
2287 static BOOL get_system_dirs(void)
2288 {
2289     HKEY hkey;
2290     DWORD type, size;
2291
2292     if (RegOpenKey(HKEY_LOCAL_MACHINE,
2293                    "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
2294         return FALSE;
2295
2296     size = MAX_PATH;
2297     if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
2298         RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
2299     {
2300         RegCloseKey(hkey);
2301         return FALSE;
2302     }
2303
2304     size = MAX_PATH;
2305     if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
2306         RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
2307     {
2308         RegCloseKey(hkey);
2309         return FALSE;
2310     }
2311
2312     RegCloseKey(hkey);
2313
2314     if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH))
2315         return FALSE;
2316
2317     return TRUE;
2318 }
2319
2320 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
2321 {
2322     HANDLE file;
2323     DWORD written;
2324
2325     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2326     if (file == INVALID_HANDLE_VALUE)
2327         return;
2328
2329     WriteFile(file, data, strlen(data), &written, NULL);
2330
2331     if (size)
2332     {
2333         SetFilePointer(file, size, NULL, FILE_BEGIN);
2334         SetEndOfFile(file);
2335     }
2336
2337     CloseHandle(file);
2338 }
2339
2340 #define create_file(name, size) create_file_data(name, name, size)
2341
2342 static void create_test_files(void)
2343 {
2344     CreateDirectoryA("msitest", NULL);
2345     create_file("msitest\\one.txt", 100);
2346     CreateDirectoryA("msitest\\first", NULL);
2347     create_file("msitest\\first\\two.txt", 100);
2348     CreateDirectoryA("msitest\\second", NULL);
2349     create_file("msitest\\second\\three.txt", 100);
2350
2351     create_file("four.txt", 100);
2352     create_file("five.txt", 100);
2353     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
2354
2355     create_file("msitest\\filename", 100);
2356     create_file("msitest\\service.exe", 100);
2357     create_file("msitest\\service2.exe", 100);
2358
2359     DeleteFileA("four.txt");
2360     DeleteFileA("five.txt");
2361 }
2362
2363 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
2364 {
2365     CHAR path[MAX_PATH];
2366
2367     lstrcpyA(path, PROG_FILES_DIR);
2368     lstrcatA(path, "\\");
2369     lstrcatA(path, rel_path);
2370
2371     if (is_file)
2372         return DeleteFileA(path);
2373     else
2374         return RemoveDirectoryA(path);
2375 }
2376
2377 static void delete_test_files(void)
2378 {
2379     DeleteFileA("msitest.msi");
2380     DeleteFileA("msitest.cab");
2381     DeleteFileA("msitest\\second\\three.txt");
2382     DeleteFileA("msitest\\first\\two.txt");
2383     DeleteFileA("msitest\\one.txt");
2384     DeleteFileA("msitest\\service.exe");
2385     DeleteFileA("msitest\\service2.exe");
2386     DeleteFileA("msitest\\filename");
2387     RemoveDirectoryA("msitest\\second");
2388     RemoveDirectoryA("msitest\\first");
2389     RemoveDirectoryA("msitest");
2390 }
2391
2392 static void write_file(const CHAR *filename, const char *data, int data_size)
2393 {
2394     DWORD size;
2395     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2396     WriteFile(hf, data, data_size, &size, NULL);
2397     CloseHandle(hf);
2398 }
2399
2400 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
2401 {
2402     MSIHANDLE summary;
2403     UINT r;
2404
2405     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
2406     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2407
2408     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
2409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2410
2411     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2412                                    "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
2413     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2414
2415     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
2416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2417
2418     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
2419     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2420
2421     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2423
2424     /* write the summary changes back to the stream */
2425     r = MsiSummaryInfoPersist(summary);
2426     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2427
2428     MsiCloseHandle(summary);
2429 }
2430
2431 #define create_database(name, tables, num_tables) \
2432     create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
2433
2434 #define create_database_template(name, tables, num_tables, version, template) \
2435     create_database_wordcount(name, tables, num_tables, version, 0, template);
2436
2437 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
2438                                       int num_tables, INT version, INT wordcount,
2439                                       const char *template)
2440 {
2441     MSIHANDLE db;
2442     UINT r;
2443     int j;
2444
2445     r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
2446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2447
2448     /* import the tables into the database */
2449     for (j = 0; j < num_tables; j++)
2450     {
2451         const msi_table *table = &tables[j];
2452
2453         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
2454
2455         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
2456         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2457
2458         DeleteFileA(table->filename);
2459     }
2460
2461     write_msi_summary_info(db, version, wordcount, template);
2462
2463     r = MsiDatabaseCommit(db);
2464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2465
2466     MsiCloseHandle(db);
2467 }
2468
2469 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
2470 {
2471     RESTOREPOINTINFOA spec;
2472
2473     spec.dwEventType = event_type;
2474     spec.dwRestorePtType = APPLICATION_INSTALL;
2475     spec.llSequenceNumber = status->llSequenceNumber;
2476     lstrcpyA(spec.szDescription, "msitest restore point");
2477
2478     return pSRSetRestorePointA(&spec, status);
2479 }
2480
2481 static void remove_restore_point(DWORD seq_number)
2482 {
2483     DWORD res;
2484
2485     res = pSRRemoveRestorePoint(seq_number);
2486     if (res != ERROR_SUCCESS)
2487         trace("Failed to remove the restore point : %08x\n", res);
2488 }
2489
2490 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
2491 {
2492     if (pRegDeleteKeyExA)
2493         return pRegDeleteKeyExA( key, subkey, access, 0 );
2494     return RegDeleteKeyA( key, subkey );
2495 }
2496
2497 static BOOL file_exists(LPCSTR file)
2498 {
2499     return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
2500 }
2501
2502 static BOOL pf_exists(LPCSTR file)
2503 {
2504     CHAR path[MAX_PATH];
2505
2506     lstrcpyA(path, PROG_FILES_DIR);
2507     lstrcatA(path, "\\");
2508     lstrcatA(path, file);
2509
2510     return file_exists(path);
2511 }
2512
2513 static void delete_pfmsitest_files(void)
2514 {
2515     SHFILEOPSTRUCT shfl;
2516     CHAR path[MAX_PATH+11];
2517
2518     lstrcpyA(path, PROG_FILES_DIR);
2519     lstrcatA(path, "\\msitest\\*");
2520     path[strlen(path) + 1] = '\0';
2521
2522     shfl.hwnd = NULL;
2523     shfl.wFunc = FO_DELETE;
2524     shfl.pFrom = path;
2525     shfl.pTo = NULL;
2526     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT | FOF_NOERRORUI;
2527
2528     SHFileOperation(&shfl);
2529
2530     lstrcpyA(path, PROG_FILES_DIR);
2531     lstrcatA(path, "\\msitest");
2532     RemoveDirectoryA(path);
2533 }
2534
2535 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
2536 {
2537     char val[MAX_PATH];
2538     DWORD size, type;
2539     LONG res;
2540
2541     size = MAX_PATH;
2542     val[0] = '\0';
2543     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
2544
2545     if (res != ERROR_SUCCESS ||
2546         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
2547     {
2548         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2549         return;
2550     }
2551
2552     if (!expected)
2553         ok_(__FILE__, line)(lstrlenA(val) == 0, "Expected empty string, got %s\n", val);
2554     else
2555     {
2556         if (bcase)
2557             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
2558         else
2559             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
2560     }
2561 }
2562
2563 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
2564 {
2565     DWORD val, size, type;
2566     LONG res;
2567
2568     size = sizeof(DWORD);
2569     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2570
2571     if (res != ERROR_SUCCESS || type != REG_DWORD)
2572     {
2573         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2574         return;
2575     }
2576
2577     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
2578 }
2579
2580 static void check_reg_dword4(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3,
2581                              DWORD expected4, DWORD line)
2582 {
2583     DWORD val, size, type;
2584     LONG res;
2585
2586     size = sizeof(DWORD);
2587     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2588
2589     if (res != ERROR_SUCCESS || type != REG_DWORD)
2590     {
2591         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2592         return;
2593     }
2594
2595     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4,
2596         "Expected %d, %d, %d or %d, got %d\n", expected1, expected2, expected3, expected4, val);
2597 }
2598
2599 static void check_reg_dword5(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3,
2600                              DWORD expected4, DWORD expected5, DWORD line)
2601 {
2602     DWORD val, size, type;
2603     LONG res;
2604
2605     size = sizeof(DWORD);
2606     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2607
2608     if (res != ERROR_SUCCESS || type != REG_DWORD)
2609     {
2610         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2611         return;
2612     }
2613
2614     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4 ||
2615         val == expected5,
2616         "Expected %d, %d, %d, %d or %d, got %d\n", expected1, expected2, expected3, expected4, expected5, val);
2617 }
2618
2619 #define CHECK_REG_STR(prodkey, name, expected) \
2620     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
2621
2622 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
2623     do { \
2624         check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
2625         RegDeleteValueA(prodkey, name); \
2626     } while(0)
2627
2628 #define CHECK_REG_ISTR(prodkey, name, expected) \
2629     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
2630
2631 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
2632     do { \
2633         check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
2634         RegDeleteValueA(prodkey, name); \
2635     } while(0)
2636
2637 #define CHECK_REG_DWORD(prodkey, name, expected) \
2638     check_reg_dword(prodkey, name, expected, __LINE__);
2639
2640 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
2641     do { \
2642         check_reg_dword(prodkey, name, expected, __LINE__); \
2643         RegDeleteValueA(prodkey, name); \
2644     } while(0)
2645
2646 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
2647     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
2648
2649 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
2650     do { \
2651         check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
2652         RegDeleteValueA(prodkey, name); \
2653     } while(0)
2654
2655 #define CHECK_REG_DWORD4(prodkey, name, expected1, expected2, expected3, expected4) \
2656     check_reg_dword4(prodkey, name, expected1, expected2, expected3, expected4, __LINE__);
2657
2658 #define CHECK_DEL_REG_DWORD5(prodkey, name, expected1, expected2, expected3, expected4 ,expected5) \
2659     do { \
2660         check_reg_dword5(prodkey, name, expected1, expected2, expected3, expected4, expected5, __LINE__); \
2661         RegDeleteValueA(prodkey, name); \
2662     } while(0)
2663
2664 static void get_date_str(LPSTR date)
2665 {
2666     SYSTEMTIME systime;
2667
2668     static const char date_fmt[] = "%d%02d%02d";
2669     GetLocalTime(&systime);
2670     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
2671 }
2672
2673 static void test_register_product(void)
2674 {
2675     UINT r;
2676     LONG res;
2677     HKEY hkey, props, usage;
2678     LPSTR usersid;
2679     char date[MAX_PATH], temp[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH];
2680     DWORD size, type;
2681     REGSAM access = KEY_ALL_ACCESS;
2682
2683     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2684                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2685     static const CHAR uninstall_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion"
2686                                            "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2687     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2688                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2689     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2690                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2691     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2692                                     "\\51AAE0C44620A5E4788506E91F249BD2";
2693
2694     if (is_process_limited())
2695     {
2696         skip("process is limited\n");
2697         return;
2698     }
2699
2700     if (!(usersid = get_user_sid()))
2701         return;
2702
2703     get_date_str(date);
2704     GetTempPath(MAX_PATH, temp);
2705
2706     CreateDirectoryA("msitest", NULL);
2707     create_file("msitest\\maximus", 500);
2708
2709     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2710
2711     if (is_wow64)
2712         access |= KEY_WOW64_64KEY;
2713
2714     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2715
2716     /* RegisterProduct */
2717     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2718     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2719     {
2720         skip("Not enough rights to perform tests\n");
2721         goto error;
2722     }
2723     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2724     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2725     ok(delete_pf("msitest", FALSE), "Directory not created\n");
2726
2727     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
2728     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2729
2730     if (is_64bit)
2731     {
2732         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
2733         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2734     }
2735     else
2736     {
2737         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
2738         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2739     }
2740
2741     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2742     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2743     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2744     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2745     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2746     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2747     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2748     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2749     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2750     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2751     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2752     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2753     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2754     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2755     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2756     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2757     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2758     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2759     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2760     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2761     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2762     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2763     todo_wine
2764     {
2765         CHECK_DEL_REG_DWORD5(hkey, "EstimatedSize", 12, -12, 4, 10, 24);
2766     }
2767
2768     delete_key(hkey, "", access);
2769     RegCloseKey(hkey);
2770
2771     sprintf(keypath, userdata, usersid);
2772     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2774
2775     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2777
2778     size = sizeof(path);
2779     RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size);
2780     DeleteFileA(path);
2781     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2782
2783     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2784     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2785     CHECK_DEL_REG_STR(props, "InstallDate", date);
2786     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2787     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2788     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2789     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2790     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2791     CHECK_DEL_REG_STR(props, "Comments", NULL);
2792     CHECK_DEL_REG_STR(props, "Contact", NULL);
2793     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2794     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2795     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2796     CHECK_DEL_REG_STR(props, "Readme", NULL);
2797     CHECK_DEL_REG_STR(props, "Size", NULL);
2798     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2799     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2800     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2801     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2802     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2803     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2804     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2805     todo_wine
2806     {
2807         CHECK_DEL_REG_DWORD5(props, "EstimatedSize", 12, -12, 4, 10, 24);
2808     }
2809
2810     delete_key(props, "", access);
2811     RegCloseKey(props);
2812
2813     res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage);
2814     todo_wine
2815     {
2816         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2817     }
2818
2819     delete_key(usage, "", access);
2820     RegCloseKey(usage);
2821     delete_key(hkey, "", access);
2822     RegCloseKey(hkey);
2823
2824     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey);
2825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2826
2827     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2828
2829     delete_key(hkey, "", access);
2830     RegCloseKey(hkey);
2831
2832     /* RegisterProduct, machine */
2833     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
2834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2835     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2836     ok(delete_pf("msitest", FALSE), "Directory not created\n");
2837
2838     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, userugkey, 0, access, &hkey);
2839     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2840
2841     if (is_64bit)
2842     {
2843         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
2844         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2845     }
2846     else
2847     {
2848         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
2849         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2850     }
2851
2852     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2853     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2854     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2855     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2856     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2857     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2858     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2859     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2860     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2861     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2862     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2863     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2864     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2865     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2866     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2867     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2868     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2869     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2870     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2871     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2872     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2873     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2874     todo_wine
2875     {
2876         CHECK_DEL_REG_DWORD5(hkey, "EstimatedSize", 12, -12, 4, 10, 24);
2877     }
2878
2879     delete_key(hkey, "", access);
2880     RegCloseKey(hkey);
2881
2882     sprintf(keypath, userdata, "S-1-5-18");
2883     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2884     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2885
2886     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2888
2889     size = sizeof(path);
2890     RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size);
2891     DeleteFileA(path);
2892     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2893
2894     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2895     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2896     CHECK_DEL_REG_STR(props, "InstallDate", date);
2897     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2898     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2899     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2900     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2901     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2902     CHECK_DEL_REG_STR(props, "Comments", NULL);
2903     CHECK_DEL_REG_STR(props, "Contact", NULL);
2904     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2905     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2906     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2907     CHECK_DEL_REG_STR(props, "Readme", NULL);
2908     CHECK_DEL_REG_STR(props, "Size", NULL);
2909     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2910     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2911     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2912     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2913     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2914     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2915     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
2916     todo_wine
2917     {
2918         CHECK_DEL_REG_DWORD5(props, "EstimatedSize", 12, -12, 4, 10, 24);
2919     }
2920
2921     delete_key(props, "", access);
2922     RegCloseKey(props);
2923
2924     res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage);
2925     todo_wine
2926     {
2927         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2928     }
2929
2930     delete_key(usage, "", access);
2931     RegCloseKey(usage);
2932     delete_key(hkey, "", access);
2933     RegCloseKey(hkey);
2934
2935     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey);
2936     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2937
2938     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
2939
2940     delete_key(hkey, "", access);
2941     RegCloseKey(hkey);
2942
2943 error:
2944     DeleteFile(msifile);
2945     DeleteFile("msitest\\maximus");
2946     RemoveDirectory("msitest");
2947     HeapFree(GetProcessHeap(), 0, usersid);
2948 }
2949
2950 static void test_publish_product(void)
2951 {
2952     UINT r;
2953     LONG res;
2954     LPSTR usersid;
2955     HKEY sourcelist, net, props;
2956     HKEY hkey, patches, media;
2957     CHAR keypath[MAX_PATH];
2958     CHAR temp[MAX_PATH];
2959     CHAR path[MAX_PATH];
2960     BOOL old_installer = FALSE;
2961     REGSAM access = KEY_ALL_ACCESS;
2962
2963     static const CHAR prodpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2964                                    "\\Installer\\UserData\\%s\\Products"
2965                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2966     static const CHAR cuprodpath[] = "Software\\Microsoft\\Installer\\Products"
2967                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2968     static const CHAR cuupgrades[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2969                                      "\\51AAE0C44620A5E4788506E91F249BD2";
2970     static const CHAR badprod[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2971                                   "\\Installer\\Products"
2972                                   "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2973     static const CHAR machprod[] = "Software\\Classes\\Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2974     static const CHAR machup[] = "Software\\Classes\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2975
2976     if (is_process_limited())
2977     {
2978         skip("process is limited\n");
2979         return;
2980     }
2981
2982     if (!(usersid = get_user_sid()))
2983         return;
2984
2985     GetTempPath(MAX_PATH, temp);
2986
2987     CreateDirectoryA("msitest", NULL);
2988     create_file("msitest\\maximus", 500);
2989
2990     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2991
2992     if (is_wow64)
2993         access |= KEY_WOW64_64KEY;
2994
2995     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2996
2997     /* PublishProduct, current user */
2998     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
2999     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3000     {
3001         skip("Not enough rights to perform tests\n");
3002         goto error;
3003     }
3004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3005     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3006     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3007
3008     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey);
3009     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3010
3011     sprintf(keypath, prodpath, usersid);
3012     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3013     if (res == ERROR_FILE_NOT_FOUND)
3014     {
3015         res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
3016         if (res == ERROR_SUCCESS)
3017         {
3018             win_skip("Windows Installer < 3.0 detected\n");
3019             RegCloseKey(hkey);
3020             old_installer = TRUE;
3021             goto currentuser;
3022         }
3023         else
3024         {
3025             win_skip("Install failed, no need to continue\n");
3026             return;
3027         }
3028     }
3029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3030
3031     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
3032     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3033
3034     res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches);
3035     todo_wine
3036     {
3037         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3038         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
3039     }
3040
3041     delete_key(patches, "", access);
3042     RegCloseKey(patches);
3043     delete_key(hkey, "", access);
3044     RegCloseKey(hkey);
3045
3046 currentuser:
3047     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
3048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3049
3050     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
3051     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052C94DA02821EECD05F2F");
3052     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3053     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3054     if (!old_installer)
3055         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
3056     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
3057     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
3058     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
3059     CHECK_DEL_REG_STR(hkey, "Clients", ":");
3060
3061     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
3062     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3063
3064     lstrcpyA(path, "n;1;");
3065     lstrcatA(path, temp);
3066     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
3067     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
3068
3069     res = RegOpenKeyA(sourcelist, "Net", &net);
3070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3071
3072     CHECK_DEL_REG_STR(net, "1", temp);
3073
3074     RegDeleteKeyA(net, "");
3075     RegCloseKey(net);
3076
3077     res = RegOpenKeyA(sourcelist, "Media", &media);
3078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3079
3080     CHECK_DEL_REG_STR(media, "1", "DISK1;");
3081
3082     RegDeleteKeyA(media, "");
3083     RegCloseKey(media);
3084     RegDeleteKeyA(sourcelist, "");
3085     RegCloseKey(sourcelist);
3086     RegDeleteKeyA(hkey, "");
3087     RegCloseKey(hkey);
3088
3089     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
3090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3091
3092     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3093
3094     RegDeleteKeyA(hkey, "");
3095     RegCloseKey(hkey);
3096
3097     /* PublishProduct, machine */
3098     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
3099     if (old_installer)
3100         goto machprod;
3101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3102     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3103     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3104
3105     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey);
3106     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3107
3108     sprintf(keypath, prodpath, "S-1-5-18");
3109     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3111
3112     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
3113     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3114
3115     res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches);
3116     todo_wine
3117     {
3118         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3119         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
3120     }
3121
3122     delete_key(patches, "", access);
3123     RegCloseKey(patches);
3124     delete_key(hkey, "", access);
3125     RegCloseKey(hkey);
3126
3127 machprod:
3128     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machprod, 0, access, &hkey);
3129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3130
3131     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
3132     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052C94DA02821EECD05F2F");
3133     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3134     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3135     if (!old_installer)
3136         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
3137     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
3138     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
3139     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
3140     CHECK_DEL_REG_STR(hkey, "Clients", ":");
3141
3142     res = RegOpenKeyExA(hkey, "SourceList", 0, access, &sourcelist);
3143     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3144
3145     lstrcpyA(path, "n;1;");
3146     lstrcatA(path, temp);
3147     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
3148     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
3149
3150     res = RegOpenKeyExA(sourcelist, "Net", 0, access, &net);
3151     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3152
3153     CHECK_DEL_REG_STR(net, "1", temp);
3154
3155     res = delete_key(net, "", access);
3156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3157     RegCloseKey(net);
3158
3159     res = RegOpenKeyExA(sourcelist, "Media", 0, access, &media);
3160     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3161
3162     CHECK_DEL_REG_STR(media, "1", "DISK1;");
3163
3164     res = delete_key(media, "", access);
3165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3166     RegCloseKey(media);
3167     res = delete_key(sourcelist, "", access);
3168     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3169     RegCloseKey(sourcelist);
3170     res = delete_key(hkey, "", access);
3171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3172     RegCloseKey(hkey);
3173
3174     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machup, 0, access, &hkey);
3175     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3176
3177     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3178
3179     res = delete_key(hkey, "", access);
3180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3181     RegCloseKey(hkey);
3182
3183 error:
3184     DeleteFile(msifile);
3185     DeleteFile("msitest\\maximus");
3186     RemoveDirectory("msitest");
3187     HeapFree(GetProcessHeap(), 0, usersid);
3188 }
3189
3190 static void test_publish_features(void)
3191 {
3192     UINT r;
3193     LONG res;
3194     HKEY hkey;
3195     LPSTR usersid;
3196     CHAR keypath[MAX_PATH];
3197     REGSAM access = KEY_ALL_ACCESS;
3198
3199     static const CHAR cupath[] = "Software\\Microsoft\\Installer\\Features"
3200                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3201     static const CHAR udfeatpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3202                                      "\\Installer\\UserData\\%s\\Products"
3203                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
3204     static const CHAR udpridpath[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3205                                      "\\Installer\\UserData\\%s\\Products"
3206                                      "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3207     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
3208                                   "\\Installer\\Features";
3209     static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
3210                                     "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3211
3212     if (is_process_limited())
3213     {
3214         skip("process is limited\n");
3215         return;
3216     }
3217
3218     if (!(usersid = get_user_sid()))
3219         return;
3220
3221     CreateDirectoryA("msitest", NULL);
3222     create_file("msitest\\maximus", 500);
3223
3224     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3225
3226     if (is_wow64)
3227         access |= KEY_WOW64_64KEY;
3228
3229     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3230
3231     /* PublishFeatures, current user */
3232     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3233     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3234     {
3235         skip("Not enough rights to perform tests\n");
3236         goto error;
3237     }
3238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3239     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3240     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3241
3242     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey);
3243     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3244
3245     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey);
3246     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3247
3248     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3249     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3250
3251     CHECK_REG_STR(hkey, "feature", "");
3252     CHECK_REG_STR(hkey, "montecristo", "");
3253
3254     RegDeleteValueA(hkey, "feature");
3255     RegDeleteValueA(hkey, "montecristo");
3256     delete_key(hkey, "", access);
3257     RegCloseKey(hkey);
3258
3259     sprintf(keypath, udfeatpath, usersid);
3260     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3262
3263     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3264     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3265
3266     RegDeleteValueA(hkey, "feature");
3267     RegDeleteValueA(hkey, "montecristo");
3268     delete_key(hkey, "", access);
3269     RegCloseKey(hkey);
3270     sprintf(keypath, udpridpath, usersid);
3271     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3272
3273     /* PublishFeatures, machine */
3274     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
3275     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3276     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3277     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3278
3279     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey);
3280     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3281
3282     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3283     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3284     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey);
3285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3286
3287     CHECK_REG_STR(hkey, "feature", "");
3288     CHECK_REG_STR(hkey, "montecristo", "");
3289
3290     RegDeleteValueA(hkey, "feature");
3291     RegDeleteValueA(hkey, "montecristo");
3292     delete_key(hkey, "", access);
3293     RegCloseKey(hkey);
3294
3295     sprintf(keypath, udfeatpath, "S-1-5-18");
3296     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3298
3299     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3300     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3301
3302     RegDeleteValueA(hkey, "feature");
3303     RegDeleteValueA(hkey, "montecristo");
3304     delete_key(hkey, "", access);
3305     RegCloseKey(hkey);
3306     sprintf(keypath, udpridpath, "S-1-5-18");
3307     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3308
3309 error:
3310     DeleteFile(msifile);
3311     DeleteFile("msitest\\maximus");
3312     RemoveDirectory("msitest");
3313     HeapFree(GetProcessHeap(), 0, usersid);
3314 }
3315
3316 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
3317 {
3318     DWORD len = 0;
3319     LPSTR val;
3320     LONG r;
3321
3322     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
3323     if (r != ERROR_SUCCESS)
3324         return NULL;
3325
3326     len += sizeof (WCHAR);
3327     val = HeapAlloc(GetProcessHeap(), 0, len);
3328     if (!val) return NULL;
3329     val[0] = 0;
3330     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
3331     return val;
3332 }
3333
3334 static void get_owner_company(LPSTR *owner, LPSTR *company)
3335 {
3336     LONG res;
3337     HKEY hkey;
3338     REGSAM access = KEY_ALL_ACCESS;
3339
3340     *owner = *company = NULL;
3341
3342     if (is_wow64)
3343         access |= KEY_WOW64_64KEY;
3344
3345     res = RegOpenKeyA(HKEY_CURRENT_USER,
3346                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
3347     if (res == ERROR_SUCCESS)
3348     {
3349         *owner = reg_get_val_str(hkey, "DefName");
3350         *company = reg_get_val_str(hkey, "DefCompany");
3351         RegCloseKey(hkey);
3352     }
3353
3354     if (!*owner || !*company)
3355     {
3356         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
3357                             "Software\\Microsoft\\Windows\\CurrentVersion", 0, access, &hkey);
3358         if (res == ERROR_SUCCESS)
3359         {
3360             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3361             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3362             RegCloseKey(hkey);
3363         }
3364     }
3365
3366     if (!*owner || !*company)
3367     {
3368         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
3369                             "Software\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey);
3370         if (res == ERROR_SUCCESS)
3371         {
3372             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3373             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3374             RegCloseKey(hkey);
3375         }
3376     }
3377 }
3378
3379 static void test_register_user(void)
3380 {
3381     UINT r;
3382     LONG res;
3383     HKEY props;
3384     LPSTR usersid;
3385     LPSTR owner, company;
3386     CHAR keypath[MAX_PATH];
3387     REGSAM access = KEY_ALL_ACCESS;
3388
3389     static const CHAR keypropsfmt[] =
3390         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3391         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
3392     static const CHAR keypridfmt[] =
3393         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3394         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3395
3396     if (is_process_limited())
3397     {
3398         skip("process is limited\n");
3399         return;
3400     }
3401
3402     if (!(usersid = get_user_sid()))
3403         return;
3404
3405     get_owner_company(&owner, &company);
3406
3407     CreateDirectoryA("msitest", NULL);
3408     create_file("msitest\\maximus", 500);
3409
3410     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3411
3412     if (is_wow64)
3413         access |= KEY_WOW64_64KEY;
3414
3415     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3416
3417     /* RegisterUser, per-user */
3418     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
3419     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3420     {
3421         skip("Not enough rights to perform tests\n");
3422         goto error;
3423     }
3424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3425     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3426     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3427
3428     sprintf(keypath, keypropsfmt, usersid);
3429     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
3430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3431
3432     CHECK_REG_STR(props, "ProductID", "none");
3433     CHECK_REG_STR(props, "RegCompany", company);
3434     CHECK_REG_STR(props, "RegOwner", owner);
3435
3436     RegDeleteValueA(props, "ProductID");
3437     RegDeleteValueA(props, "RegCompany");
3438     RegDeleteValueA(props, "RegOwner");
3439     delete_key(props, "", access);
3440     RegCloseKey(props);
3441     sprintf(keypath, keypridfmt, usersid);
3442     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3443
3444     /* RegisterUser, machine */
3445     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
3446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3447     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3448     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3449
3450     sprintf(keypath, keypropsfmt, "S-1-5-18");
3451     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
3452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3453
3454     CHECK_REG_STR(props, "ProductID", "none");
3455     CHECK_REG_STR(props, "RegCompany", company);
3456     CHECK_REG_STR(props, "RegOwner", owner);
3457
3458     RegDeleteValueA(props, "ProductID");
3459     RegDeleteValueA(props, "RegCompany");
3460     RegDeleteValueA(props, "RegOwner");
3461     delete_key(props, "", access);
3462     RegCloseKey(props);
3463     sprintf(keypath, keypridfmt, "S-1-5-18");
3464     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3465
3466 error:
3467     HeapFree(GetProcessHeap(), 0, company);
3468     HeapFree(GetProcessHeap(), 0, owner);
3469
3470     DeleteFile(msifile);
3471     DeleteFile("msitest\\maximus");
3472     RemoveDirectory("msitest");
3473     LocalFree(usersid);
3474 }
3475
3476 static void test_process_components(void)
3477 {
3478     UINT r;
3479     LONG res;
3480     DWORD size;
3481     HKEY comp, hkey;
3482     LPSTR usersid;
3483     CHAR val[MAX_PATH];
3484     CHAR keypath[MAX_PATH];
3485     CHAR program_files_maximus[MAX_PATH];
3486     REGSAM access = KEY_ALL_ACCESS;
3487
3488     static const CHAR keyfmt[] =
3489         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3490         "UserData\\%s\\Components\\%s";
3491     static const CHAR compkey[] =
3492         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
3493
3494     if (is_process_limited())
3495     {
3496         skip("process is limited\n");
3497         return;
3498     }
3499
3500     if (!(usersid = get_user_sid()))
3501         return;
3502
3503     CreateDirectoryA("msitest", NULL);
3504     create_file("msitest\\maximus", 500);
3505
3506     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
3507
3508     if (is_wow64)
3509         access |= KEY_WOW64_64KEY;
3510
3511     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3512
3513     /* ProcessComponents, per-user */
3514     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3515     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3516     {
3517         skip("Not enough rights to perform tests\n");
3518         goto error;
3519     }
3520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3521     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3522     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3523
3524     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
3525     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3527
3528     size = MAX_PATH;
3529     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3530                            NULL, NULL, (LPBYTE)val, &size);
3531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3532
3533     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
3534     lstrcatA(program_files_maximus,"\\msitest\\maximus");
3535
3536     ok(!lstrcmpiA(val, program_files_maximus),
3537        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3538
3539     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3540     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3541
3542     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3543     delete_key(comp, "", access);
3544     RegCloseKey(comp);
3545
3546     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
3547     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3549
3550     size = MAX_PATH;
3551     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3552                            NULL, NULL, (LPBYTE)val, &size);
3553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3554     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3555        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3556
3557     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3558     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3559
3560     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3561     delete_key(comp, "", access);
3562     RegCloseKey(comp);
3563
3564     /* ProcessComponents, machine */
3565     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
3566     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3567     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3568     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3569
3570     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
3571     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3573
3574     size = MAX_PATH;
3575     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3576                            NULL, NULL, (LPBYTE)val, &size);
3577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3578     ok(!lstrcmpiA(val, program_files_maximus),
3579        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3580
3581     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3582     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3583
3584     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3585     delete_key(comp, "", access);
3586     RegCloseKey(comp);
3587
3588     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
3589     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3591
3592     size = MAX_PATH;
3593     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3594                            NULL, NULL, (LPBYTE)val, &size);
3595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3596     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3597        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3598
3599     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3600     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3601
3602     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3603     delete_key(comp, "", access);
3604     RegCloseKey(comp);
3605
3606 error:
3607     DeleteFile(msifile);
3608     DeleteFile("msitest\\maximus");
3609     RemoveDirectory("msitest");
3610     LocalFree(usersid);
3611 }
3612
3613 static void test_publish(void)
3614 {
3615     static const char subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3616     static const char subkey_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3617     UINT r;
3618     LONG res;
3619     HKEY uninstall, prodkey, uninstall_32node = NULL;
3620     INSTALLSTATE state;
3621     char date[MAX_PATH], temp[MAX_PATH], prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3622     REGSAM access = KEY_ALL_ACCESS;
3623     DWORD error;
3624
3625     if (!pMsiQueryFeatureStateExA)
3626     {
3627         win_skip("MsiQueryFeatureStateExA is not available\n");
3628         return;
3629     }
3630     if (is_process_limited())
3631     {
3632         skip("process is limited\n");
3633         return;
3634     }
3635
3636     get_date_str(date);
3637     GetTempPath(MAX_PATH, temp);
3638
3639     if (is_wow64)
3640         access |= KEY_WOW64_64KEY;
3641
3642     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, KEY_ALL_ACCESS, &uninstall);
3643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3644
3645     if (is_64bit)
3646     {
3647         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey_32node, 0, KEY_ALL_ACCESS, &uninstall_32node);
3648         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3649     }
3650
3651     CreateDirectoryA("msitest", NULL);
3652     create_file("msitest\\maximus", 500);
3653
3654     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3655
3656     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3657
3658     state = MsiQueryProductState(prodcode);
3659     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3660
3661     state = MsiQueryFeatureState(prodcode, "feature");
3662     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3663
3664     state = 0xdead;
3665     SetLastError(0xdeadbeef);
3666     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
3667     error = GetLastError();
3668     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
3669     ok(state == 0xdead, "got %d\n", state);
3670     ok(error == 0xdeadbeef, "got %u\n", error);
3671
3672     state = 0xdead;
3673     SetLastError(0xdeadbeef);
3674     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
3675     error = GetLastError();
3676     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
3677     ok(state == 0xdead, "got %d\n", state);
3678     ok(error == ERROR_SUCCESS, "got %u\n", error);
3679
3680     state = 0xdead;
3681     SetLastError(0xdeadbeef);
3682     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
3683     error = GetLastError();
3684     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
3685     ok(state == 0xdead, "got %d\n", state);
3686     ok(error == ERROR_SUCCESS, "got %u\n", error);
3687
3688     state = MsiQueryFeatureState(prodcode, "feature");
3689     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3690
3691     state = MsiQueryFeatureState(prodcode, "montecristo");
3692     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3693
3694     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3695                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3696     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3697     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3698
3699     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3700     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3701
3702     /* nothing published */
3703     r = MsiInstallProductA(msifile, NULL);
3704     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3705     {
3706         skip("Not enough rights to perform tests\n");
3707         goto error;
3708     }
3709     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3710     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3711     ok(pf_exists("msitest"), "File not installed\n");
3712
3713     state = MsiQueryProductState(prodcode);
3714     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3715
3716     state = MsiQueryFeatureState(prodcode, "feature");
3717     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3718
3719     state = MsiQueryFeatureState(prodcode, "montecristo");
3720     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3721
3722     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3723                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3724     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3725     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3726
3727     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3728     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3729
3730     /* PublishProduct and RegisterProduct */
3731     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
3732     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3733     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3734     ok(pf_exists("msitest"), "File not installed\n");
3735
3736     state = MsiQueryProductState(prodcode);
3737     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3738
3739     state = MsiQueryFeatureState(prodcode, "feature");
3740     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3741
3742     state = MsiQueryFeatureState(prodcode, "montecristo");
3743     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3744
3745     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3746                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3747     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3748     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3749
3750     if (is_64bit)
3751     {
3752         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3753         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3754     }
3755     else
3756     {
3757         res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3758         if (is_wow64 && res == ERROR_FILE_NOT_FOUND) /* XP - Vista, Wow64 */
3759             res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3760         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3761     }
3762
3763     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3764     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3765     CHECK_REG_STR(prodkey, "InstallDate", date);
3766     CHECK_REG_STR(prodkey, "InstallSource", temp);
3767     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3768     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3769     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3770     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3771     CHECK_REG_STR(prodkey, "Comments", NULL);
3772     CHECK_REG_STR(prodkey, "Contact", NULL);
3773     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3774     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3775     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3776     CHECK_REG_STR(prodkey, "Readme", NULL);
3777     CHECK_REG_STR(prodkey, "Size", NULL);
3778     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3779     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3780     CHECK_REG_DWORD(prodkey, "Language", 1033);
3781     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3782     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3783     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3784     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3785     todo_wine
3786     {
3787         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3788     }
3789
3790     RegCloseKey(prodkey);
3791
3792     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3794     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3795     ok(pf_exists("msitest"), "File deleted\n");
3796
3797     state = MsiQueryProductState(prodcode);
3798     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3799
3800     state = MsiQueryFeatureState(prodcode, "feature");
3801     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3802
3803     state = MsiQueryFeatureState(prodcode, "montecristo");
3804     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3805
3806     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3807                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3808     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3809     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3810
3811     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3812     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3813
3814     /* complete install */
3815     r = MsiInstallProductA(msifile, "FULL=1");
3816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3817     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3818     ok(pf_exists("msitest"), "File not installed\n");
3819
3820     state = MsiQueryProductState(prodcode);
3821     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3822
3823     state = MsiQueryFeatureState(prodcode, "feature");
3824     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3825
3826     state = 0xdead;
3827     SetLastError(0xdeadbeef);
3828     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
3829     error = GetLastError();
3830     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
3831     ok(state == 0xdead, "got %d\n", state);
3832     ok(error == 0xdeadbeef, "got %u\n", error);
3833
3834     state = 0xdead;
3835     SetLastError(0xdeadbeef);
3836     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
3837     error = GetLastError();
3838     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
3839     ok(state == 0xdead, "got %d\n", state);
3840     ok(error == ERROR_SUCCESS, "got %u\n", error);
3841
3842     state = 0xdead;
3843     SetLastError(0xdeadbeef);
3844     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
3845     error = GetLastError();
3846     ok(r == ERROR_SUCCESS, "got %u\n", r);
3847     ok(state == INSTALLSTATE_LOCAL, "got %d\n", state);
3848     ok(error == ERROR_SUCCESS, "got %u\n", error);
3849
3850     state = MsiQueryFeatureState(prodcode, "montecristo");
3851     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3852
3853     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3854                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3855     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3856     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3857
3858     if (is_64bit)
3859     {
3860         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3861         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3862     }
3863     else
3864     {
3865         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3866         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3867     }
3868
3869     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3870     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3871     CHECK_REG_STR(prodkey, "InstallDate", date);
3872     CHECK_REG_STR(prodkey, "InstallSource", temp);
3873     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3874     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3875     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3876     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3877     CHECK_REG_STR(prodkey, "Comments", NULL);
3878     CHECK_REG_STR(prodkey, "Contact", NULL);
3879     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3880     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3881     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3882     CHECK_REG_STR(prodkey, "Readme", NULL);
3883     CHECK_REG_STR(prodkey, "Size", NULL);
3884     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3885     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3886     CHECK_REG_DWORD(prodkey, "Language", 1033);
3887     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3888     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3889     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3890     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3891     todo_wine
3892     {
3893         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3894     }
3895
3896     RegCloseKey(prodkey);
3897
3898     /* no UnpublishFeatures */
3899     r = MsiInstallProductA(msifile, "REMOVE=ALL");
3900     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3901     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
3902     ok(!pf_exists("msitest"), "Directory not deleted\n");
3903
3904     state = MsiQueryProductState(prodcode);
3905     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3906
3907     state = MsiQueryFeatureState(prodcode, "feature");
3908     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3909
3910     state = MsiQueryFeatureState(prodcode, "montecristo");
3911     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3912
3913     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3914                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3915     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3916     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3917
3918     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3919     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3920
3921     /* complete install */
3922     r = MsiInstallProductA(msifile, "FULL=1");
3923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3924     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3925     ok(pf_exists("msitest"), "File not installed\n");
3926
3927     state = MsiQueryProductState(prodcode);
3928     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3929
3930     state = MsiQueryFeatureState(prodcode, "feature");
3931     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3932
3933     state = MsiQueryFeatureState(prodcode, "montecristo");
3934     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3935
3936     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3937                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3938     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3939     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3940
3941     if (is_64bit)
3942     {
3943         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3944         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3945     }
3946     else
3947     {
3948         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3949         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3950     }
3951
3952     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3953     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3954     CHECK_REG_STR(prodkey, "InstallDate", date);
3955     CHECK_REG_STR(prodkey, "InstallSource", temp);
3956     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3957     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3958     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3959     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3960     CHECK_REG_STR(prodkey, "Comments", NULL);
3961     CHECK_REG_STR(prodkey, "Contact", NULL);
3962     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3963     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3964     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3965     CHECK_REG_STR(prodkey, "Readme", NULL);
3966     CHECK_REG_STR(prodkey, "Size", NULL);
3967     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3968     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3969     CHECK_REG_DWORD(prodkey, "Language", 1033);
3970     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3971     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3972     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3973     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3974     todo_wine
3975     {
3976         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3977     }
3978
3979     RegCloseKey(prodkey);
3980
3981     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
3982     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
3983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3984     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3985     ok(pf_exists("msitest"), "Directory deleted\n");
3986
3987     state = MsiQueryProductState(prodcode);
3988     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3989
3990     state = MsiQueryFeatureState(prodcode, "feature");
3991     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3992
3993     state = MsiQueryFeatureState(prodcode, "montecristo");
3994     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3995
3996     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3997                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3999     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4000
4001     if (is_64bit)
4002     {
4003         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4004         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4005     }
4006     else
4007     {
4008         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4009         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4010     }
4011
4012     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4013     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4014     CHECK_REG_STR(prodkey, "InstallDate", date);
4015     CHECK_REG_STR(prodkey, "InstallSource", temp);
4016     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4017     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4018     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4019     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4020     CHECK_REG_STR(prodkey, "Comments", NULL);
4021     CHECK_REG_STR(prodkey, "Contact", NULL);
4022     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4023     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4024     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4025     CHECK_REG_STR(prodkey, "Readme", NULL);
4026     CHECK_REG_STR(prodkey, "Size", NULL);
4027     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4028     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4029     CHECK_REG_DWORD(prodkey, "Language", 1033);
4030     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4031     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4032     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4033     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4034     todo_wine
4035     {
4036         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
4037     }
4038
4039     RegCloseKey(prodkey);
4040
4041     /* complete install */
4042     r = MsiInstallProductA(msifile, "FULL=1");
4043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4044     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4045     ok(pf_exists("msitest"), "File not installed\n");
4046
4047     state = MsiQueryProductState(prodcode);
4048     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4049
4050     state = MsiQueryFeatureState(prodcode, "feature");
4051     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4052
4053     state = MsiQueryFeatureState(prodcode, "montecristo");
4054     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4055
4056     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4057                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4058     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4059     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4060
4061     if (is_64bit)
4062     {
4063         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4064         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4065     }
4066     else
4067     {
4068         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4069         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4070     }
4071
4072     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4073     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4074     CHECK_REG_STR(prodkey, "InstallDate", date);
4075     CHECK_REG_STR(prodkey, "InstallSource", temp);
4076     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4077     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4078     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4079     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4080     CHECK_REG_STR(prodkey, "Comments", NULL);
4081     CHECK_REG_STR(prodkey, "Contact", NULL);
4082     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4083     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4084     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4085     CHECK_REG_STR(prodkey, "Readme", NULL);
4086     CHECK_REG_STR(prodkey, "Size", NULL);
4087     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4088     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4089     CHECK_REG_DWORD(prodkey, "Language", 1033);
4090     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4091     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4092     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4093     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4094     todo_wine
4095     {
4096         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -20, 10, 24);
4097     }
4098
4099     RegCloseKey(prodkey);
4100
4101     /* UnpublishFeatures, both features removed */
4102     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
4103     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4104     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4105     ok(!pf_exists("msitest"), "Directory not deleted\n");
4106
4107     state = MsiQueryProductState(prodcode);
4108     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4109
4110     state = MsiQueryFeatureState(prodcode, "feature");
4111     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4112
4113     state = MsiQueryFeatureState(prodcode, "montecristo");
4114     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4115
4116     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4117                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4118     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4119     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4120
4121     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
4122     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4123
4124     /* complete install */
4125     r = MsiInstallProductA(msifile, "FULL=1");
4126     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4127     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4128     ok(pf_exists("msitest"), "File not installed\n");
4129
4130     state = MsiQueryProductState(prodcode);
4131     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4132
4133     state = MsiQueryFeatureState(prodcode, "feature");
4134     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4135
4136     state = MsiQueryFeatureState(prodcode, "montecristo");
4137     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4138
4139     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4140                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4142     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4143
4144     if (is_64bit)
4145     {
4146         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4147         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4148     }
4149     else
4150     {
4151         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4152         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4153     }
4154
4155     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4156     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4157     CHECK_REG_STR(prodkey, "InstallDate", date);
4158     CHECK_REG_STR(prodkey, "InstallSource", temp);
4159     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4160     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4161     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4162     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4163     CHECK_REG_STR(prodkey, "Comments", NULL);
4164     CHECK_REG_STR(prodkey, "Contact", NULL);
4165     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4166     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4167     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4168     CHECK_REG_STR(prodkey, "Readme", NULL);
4169     CHECK_REG_STR(prodkey, "Size", NULL);
4170     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4171     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4172     CHECK_REG_DWORD(prodkey, "Language", 1033);
4173     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4174     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4175     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4176     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4177     todo_wine
4178     {
4179         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
4180     }
4181
4182     RegCloseKey(prodkey);
4183
4184     /* complete uninstall */
4185     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4186     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4187     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4188     ok(!pf_exists("msitest"), "Directory not deleted\n");
4189
4190     state = MsiQueryProductState(prodcode);
4191     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4192
4193     state = MsiQueryFeatureState(prodcode, "feature");
4194     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4195
4196     state = MsiQueryFeatureState(prodcode, "montecristo");
4197     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4198
4199     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4200                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4201     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4202     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4203
4204     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
4205     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4206
4207     /* make sure 'Program Files\msitest' is removed */
4208     delete_pfmsitest_files();
4209
4210 error:
4211     RegCloseKey(uninstall);
4212     RegCloseKey(uninstall_32node);
4213     DeleteFile(msifile);
4214     DeleteFile("msitest\\maximus");
4215     RemoveDirectory("msitest");
4216 }
4217
4218 static void test_publish_sourcelist(void)
4219 {
4220     UINT r;
4221     DWORD size;
4222     CHAR value[MAX_PATH];
4223     CHAR path[MAX_PATH];
4224     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4225
4226     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
4227     {
4228         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
4229         return;
4230     }
4231     if (is_process_limited())
4232     {
4233         skip("process is limited\n");
4234         return;
4235     }
4236
4237     CreateDirectoryA("msitest", NULL);
4238     create_file("msitest\\maximus", 500);
4239
4240     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4241
4242     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4243
4244     r = MsiInstallProductA(msifile, NULL);
4245     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4246     {
4247         skip("Not enough rights to perform tests\n");
4248         goto error;
4249     }
4250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4251     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4252     ok(pf_exists("msitest"), "File not installed\n");
4253
4254     /* nothing published */
4255     size = MAX_PATH;
4256     lstrcpyA(value, "aaa");
4257     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4258                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4259     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4260     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4261     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4262
4263     size = MAX_PATH;
4264     lstrcpyA(value, "aaa");
4265     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4266                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4267     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4268     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4269     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4270
4271     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4272     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4273     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4274     ok(pf_exists("msitest"), "File not installed\n");
4275
4276     /* after RegisterProduct */
4277     size = MAX_PATH;
4278     lstrcpyA(value, "aaa");
4279     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4280                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4281     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4282     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4283     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4284
4285     size = MAX_PATH;
4286     lstrcpyA(value, "aaa");
4287     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4288                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4289     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4290     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4291     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4292
4293     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
4294     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4295     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4296     ok(pf_exists("msitest"), "File not installed\n");
4297
4298     /* after ProcessComponents */
4299     size = MAX_PATH;
4300     lstrcpyA(value, "aaa");
4301     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4302                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4303     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4304     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4305     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4306
4307     size = MAX_PATH;
4308     lstrcpyA(value, "aaa");
4309     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4310                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4311     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4312     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4313     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4314
4315     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4316     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4317     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4318     ok(pf_exists("msitest"), "File not installed\n");
4319
4320     /* after PublishFeatures */
4321     size = MAX_PATH;
4322     lstrcpyA(value, "aaa");
4323     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4324                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4325     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4326     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4327     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4328
4329     size = MAX_PATH;
4330     lstrcpyA(value, "aaa");
4331     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4332                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4333     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4334     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4335     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4336
4337     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4338     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4339     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4340     ok(pf_exists("msitest"), "File not installed\n");
4341
4342     /* after PublishProduct */
4343     size = MAX_PATH;
4344     lstrcpyA(value, "aaa");
4345     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4346                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
4347     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4348     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
4349     ok(size == 11, "Expected 11, got %d\n", size);
4350
4351     size = MAX_PATH;
4352     lstrcpyA(value, "aaa");
4353     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4354                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATH, value, &size);
4355     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4356     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4357     ok(size == 0, "Expected 0, got %d\n", size);
4358
4359     size = MAX_PATH;
4360     lstrcpyA(value, "aaa");
4361     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4362                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPT, value, &size);
4363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4364     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4365     ok(size == 0, "Expected 0, got %d\n", size);
4366
4367     lstrcpyA(path, CURR_DIR);
4368     lstrcatA(path, "\\");
4369
4370     size = MAX_PATH;
4371     lstrcpyA(value, "aaa");
4372     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4373                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
4374     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4375     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4376     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4377
4378     size = MAX_PATH;
4379     lstrcpyA(value, "aaa");
4380     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4381                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPE, value, &size);
4382     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4383     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
4384     ok(size == 1, "Expected 1, got %d\n", size);
4385
4386     size = MAX_PATH;
4387     lstrcpyA(value, "aaa");
4388     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4389                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4390     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4391     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4392     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4393
4394     size = MAX_PATH;
4395     lstrcpyA(value, "aaa");
4396     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4397                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
4398     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4399     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4400     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4401
4402     size = MAX_PATH;
4403     lstrcpyA(value, "aaa");
4404     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4405                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
4406     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4407     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4408     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4409
4410     /* complete uninstall */
4411     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4413     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4414     ok(!pf_exists("msitest"), "Directory not deleted\n");
4415
4416     /* make sure 'Program Files\msitest' is removed */
4417     delete_pfmsitest_files();
4418
4419 error:
4420     DeleteFile(msifile);
4421     DeleteFile("msitest\\maximus");
4422     RemoveDirectory("msitest");
4423 }
4424
4425 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4426 {
4427     CHAR path[MAX_PATH];
4428
4429     lstrcpyA(path, PROG_FILES_DIR);
4430     lstrcatA(path, "\\");
4431     lstrcatA(path, file);
4432
4433     if (is_file)
4434         create_file_data(path, data, 500);
4435     else
4436         CreateDirectoryA(path, NULL);
4437 }
4438
4439 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4440
4441 static void test_remove_files(void)
4442 {
4443     UINT r;
4444
4445     if (is_process_limited())
4446     {
4447         skip("process is limited\n");
4448         return;
4449     }
4450
4451     CreateDirectoryA("msitest", NULL);
4452     create_file("msitest\\hydrogen", 500);
4453     create_file("msitest\\helium", 500);
4454     create_file("msitest\\lithium", 500);
4455
4456     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4457
4458     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4459
4460     r = MsiInstallProductA(msifile, NULL);
4461     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4462     {
4463         skip("Not enough rights to perform tests\n");
4464         goto error;
4465     }
4466     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4467     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4468     ok(!pf_exists("msitest\\helium"), "File installed\n");
4469     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4470     ok(pf_exists("msitest"), "File not installed\n");
4471
4472     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4474     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4475     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4476     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4477     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4478
4479     create_pf("msitest", FALSE);
4480     create_pf("msitest\\hydrogen", TRUE);
4481     create_pf("msitest\\helium", TRUE);
4482     create_pf("msitest\\lithium", TRUE);
4483
4484     r = MsiInstallProductA(msifile, NULL);
4485     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4486     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4487     ok(pf_exists("msitest\\helium"), "File not installed\n");
4488     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4489     ok(pf_exists("msitest"), "File not installed\n");
4490
4491     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4493     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4494     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4495     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4496     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4497
4498     create_pf("msitest", FALSE);
4499     create_pf("msitest\\furlong", TRUE);
4500     create_pf("msitest\\firkin", TRUE);
4501     create_pf("msitest\\fortnight", TRUE);
4502     create_pf("msitest\\becquerel", TRUE);
4503     create_pf("msitest\\dioptre", TRUE);
4504     create_pf("msitest\\attoparsec", TRUE);
4505     create_pf("msitest\\storeys", TRUE);
4506     create_pf("msitest\\block", TRUE);
4507     create_pf("msitest\\siriometer", TRUE);
4508     create_pf("msitest\\cabout", FALSE);
4509     create_pf("msitest\\cabout\\blocker", TRUE);
4510
4511     r = MsiInstallProductA(msifile, NULL);
4512     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4513     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4514     ok(!pf_exists("msitest\\helium"), "File installed\n");
4515     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4516     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4517     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4518     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4519     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4520     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4521     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4522     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4523     ok(!pf_exists("msitest\\block"), "File not deleted\n");
4524     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4525     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
4526     ok(pf_exists("msitest"), "File not installed\n");
4527
4528     create_pf("msitest\\furlong", TRUE);
4529     create_pf("msitest\\firkin", TRUE);
4530     create_pf("msitest\\fortnight", TRUE);
4531     create_pf("msitest\\storeys", TRUE);
4532     create_pf("msitest\\block", TRUE);
4533     create_pf("msitest\\siriometer", TRUE);
4534
4535     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4536     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4537     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4538     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4539     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4540     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4541     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4542     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4543     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4544     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4545     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4546     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4547     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4548     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4549     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4550     ok(pf_exists("msitest"), "Directory deleted\n");
4551
4552     r = MsiInstallProductA(msifile, NULL);
4553     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4554     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
4555     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
4556     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
4557     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4558     ok(pf_exists("msitest"), "Directory deleted\n");
4559
4560     delete_pf("msitest\\cabout\\blocker", TRUE);
4561
4562     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4563     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4564     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
4565     delete_pf("msitest", FALSE);
4566
4567 error:
4568     DeleteFile(msifile);
4569     DeleteFile("msitest\\hydrogen");
4570     DeleteFile("msitest\\helium");
4571     DeleteFile("msitest\\lithium");
4572     RemoveDirectory("msitest");
4573 }
4574
4575 static void test_move_files(void)
4576 {
4577     UINT r;
4578     char props[MAX_PATH];
4579
4580     if (is_process_limited())
4581     {
4582         skip("process is limited\n");
4583         return;
4584     }
4585
4586     CreateDirectoryA("msitest", NULL);
4587     create_file("msitest\\augustus", 100);
4588     create_file("cameroon", 100);
4589     create_file("djibouti", 100);
4590     create_file("egypt", 100);
4591     create_file("finland", 100);
4592     create_file("gambai", 100);
4593     create_file("honduras", 100);
4594     create_file("msitest\\india", 100);
4595     create_file("japan", 100);
4596     create_file("kenya", 100);
4597     CreateDirectoryA("latvia", NULL);
4598     create_file("nauru", 100);
4599     create_file("peru", 100);
4600     create_file("apple", 100);
4601     create_file("application", 100);
4602     create_file("ape", 100);
4603     create_file("foo", 100);
4604     create_file("fao", 100);
4605     create_file("fbod", 100);
4606     create_file("budding", 100);
4607     create_file("buddy", 100);
4608     create_file("bud", 100);
4609     create_file("bar", 100);
4610     create_file("bur", 100);
4611     create_file("bird", 100);
4612
4613     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4614
4615     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4616
4617     /* if the source or dest property is not a full path,
4618      * windows tries to access it as a network resource
4619      */
4620
4621     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4622             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4623             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4624
4625     r = MsiInstallProductA(msifile, props);
4626     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4627     {
4628         skip("Not enough rights to perform tests\n");
4629         goto error;
4630     }
4631     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4632     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4633     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4634     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4635     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4636     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4637     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4638     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4639     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4640     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4641     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4642     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4643     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4644     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4645     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
4646     /* either apple or application will be moved depending on directory order */
4647     if (!delete_pf("msitest\\apple", TRUE))
4648         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4649     else
4650         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4651     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4652     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4653     /* either fao or foo will be moved depending on directory order */
4654     if (delete_pf("msitest\\foo", TRUE))
4655         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4656     else
4657         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4658     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4659     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4660     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4661     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4662     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4663     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4664     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4665     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4666     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4667     ok(DeleteFileA("cameroon"), "File moved\n");
4668     ok(!DeleteFileA("djibouti"), "File not moved\n");
4669     ok(DeleteFileA("egypt"), "File moved\n");
4670     ok(DeleteFileA("finland"), "File moved\n");
4671     ok(DeleteFileA("gambai"), "File moved\n");
4672     ok(!DeleteFileA("honduras"), "File not moved\n");
4673     ok(DeleteFileA("msitest\\india"), "File moved\n");
4674     ok(DeleteFileA("japan"), "File moved\n");
4675     ok(!DeleteFileA("kenya"), "File not moved\n");
4676     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4677     ok(!DeleteFileA("nauru"), "File not moved\n");
4678     ok(!DeleteFileA("peru"), "File not moved\n");
4679     ok(!DeleteFileA("apple"), "File not moved\n");
4680     ok(!DeleteFileA("application"), "File not moved\n");
4681     ok(DeleteFileA("ape"), "File moved\n");
4682     ok(!DeleteFileA("foo"), "File not moved\n");
4683     ok(!DeleteFileA("fao"), "File not moved\n");
4684     ok(DeleteFileA("fbod"), "File moved\n");
4685     ok(!DeleteFileA("budding"), "File not moved\n");
4686     ok(!DeleteFileA("buddy"), "File not moved\n");
4687     ok(DeleteFileA("bud"), "File moved\n");
4688     ok(!DeleteFileA("bar"), "File not moved\n");
4689     ok(!DeleteFileA("bur"), "File not moved\n");
4690     ok(DeleteFileA("bird"), "File moved\n");
4691
4692 error:
4693     DeleteFile("cameroon");
4694     DeleteFile("djibouti");
4695     DeleteFile("egypt");
4696     DeleteFile("finland");
4697     DeleteFile("gambai");
4698     DeleteFile("honduras");
4699     DeleteFile("japan");
4700     DeleteFile("kenya");
4701     DeleteFile("nauru");
4702     DeleteFile("peru");
4703     DeleteFile("apple");
4704     DeleteFile("application");
4705     DeleteFile("ape");
4706     DeleteFile("foo");
4707     DeleteFile("fao");
4708     DeleteFile("fbod");
4709     DeleteFile("budding");
4710     DeleteFile("buddy");
4711     DeleteFile("bud");
4712     DeleteFile("bar");
4713     DeleteFile("bur");
4714     DeleteFile("bird");
4715     DeleteFile("msitest\\india");
4716     DeleteFile("msitest\\augustus");
4717     RemoveDirectory("latvia");
4718     RemoveDirectory("msitest");
4719     DeleteFile(msifile);
4720 }
4721
4722 static void test_duplicate_files(void)
4723 {
4724     UINT r;
4725
4726     if (is_process_limited())
4727     {
4728         skip("process is limited\n");
4729         return;
4730     }
4731
4732     CreateDirectoryA("msitest", NULL);
4733     create_file("msitest\\maximus", 500);
4734     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4735
4736     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4737
4738     /* fails if the destination folder is not a valid property */
4739
4740     r = MsiInstallProductA(msifile, NULL);
4741     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4742     {
4743         skip("Not enough rights to perform tests\n");
4744         goto error;
4745     }
4746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4747     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4748     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4749     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4750     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "Directory not created\n");
4751     ok(delete_pf("msitest\\this\\doesnot", FALSE), "Directory not created\n");
4752     ok(delete_pf("msitest\\this", FALSE), "Directory not created\n");
4753     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4754
4755 error:
4756     DeleteFile("msitest\\maximus");
4757     RemoveDirectory("msitest");
4758     DeleteFile(msifile);
4759 }
4760
4761 static void test_write_registry_values(void)
4762 {
4763     UINT r;
4764     LONG res;
4765     HKEY hkey;
4766     DWORD type, size;
4767     CHAR path[MAX_PATH];
4768
4769     if (is_process_limited())
4770     {
4771         skip("process is limited\n");
4772         return;
4773     }
4774
4775     CreateDirectoryA("msitest", NULL);
4776     create_file("msitest\\augustus", 500);
4777
4778     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4779
4780     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4781
4782     if (is_64bit)
4783         res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Wine\\msitest", 0, NULL, 0,
4784                               KEY_ALL_ACCESS, NULL, &hkey, NULL);
4785     else
4786         res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", 0, NULL, 0, KEY_ALL_ACCESS,
4787                               NULL, &hkey, NULL);
4788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4789
4790     res = RegSetValueExA(hkey, "Value1", 0, REG_MULTI_SZ, (const BYTE *)"two\0", 5);
4791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4792     res = RegSetValueExA(hkey, "Value2", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
4793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4794     res = RegSetValueExA(hkey, "Value3", 0, REG_MULTI_SZ, (const BYTE *)"two\0", 5);
4795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4796     res = RegSetValueExA(hkey, "Value4", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
4797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4798     res = RegSetValueExA(hkey, "Value5", 0, REG_MULTI_SZ, (const BYTE *)"one\0two\0", 9);
4799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4800     res = RegSetValueExA(hkey, "Value6", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
4801     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4802     res = RegSetValueExA(hkey, "Value7", 0, REG_SZ, (const BYTE *)"one", 4);
4803     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4804     RegCloseKey(hkey);
4805
4806     r = MsiInstallProductA(msifile, NULL);
4807     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4808     {
4809         skip("Not enough rights to perform tests\n");
4810         goto error;
4811     }
4812     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4813     ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
4814     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4815
4816     if (is_64bit)
4817         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey);
4818     else
4819         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey);
4820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4821
4822     size = MAX_PATH;
4823     type = 0xdeadbeef;
4824     memset(path, 'a', MAX_PATH);
4825     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
4826     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4827     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
4828     ok(size == 15, "Expected 15, got %d\n", size);
4829     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4830
4831     res = RegQueryValueExA(hkey, "", NULL, NULL, NULL, NULL);
4832     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4833
4834     res = action_RegDeleteTreeA(hkey, "VisualStudio", KEY_ALL_ACCESS);
4835     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4836
4837     size = MAX_PATH;
4838     type = 0xdeadbeef;
4839     memset(path, 'a', MAX_PATH);
4840     res = RegQueryValueExA(hkey, "Value1", NULL, &type, (LPBYTE)path, &size);
4841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4842     ok(!memcmp(path, "one\0", size), "Wrong multi-sz data\n");
4843     ok(size == 5, "Expected 5, got %d\n", size);
4844     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4845
4846     size = MAX_PATH;
4847     type = 0xdeadbeef;
4848     memset(path, 'a', MAX_PATH);
4849     res = RegQueryValueExA(hkey, "Value2", NULL, &type, (LPBYTE)path, &size);
4850     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4851     ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
4852     ok(size == 9, "Expected 9, got %d\n", size);
4853     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4854
4855     size = MAX_PATH;
4856     type = 0xdeadbeef;
4857     memset(path, 'a', MAX_PATH);
4858     res = RegQueryValueExA(hkey, "Value3", NULL, &type, (LPBYTE)path, &size);
4859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4860     ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
4861     ok(size == 9, "Expected 9, got %d\n", size);
4862     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4863
4864     size = MAX_PATH;
4865     type = 0xdeadbeef;
4866     memset(path, 'a', MAX_PATH);
4867     res = RegQueryValueExA(hkey, "Value4", NULL, &type, (LPBYTE)path, &size);
4868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4869     ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
4870     ok(size == 9, "Expected 9, got %d\n", size);
4871     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4872
4873     size = MAX_PATH;
4874     type = 0xdeadbeef;
4875     memset(path, 'a', MAX_PATH);
4876     res = RegQueryValueExA(hkey, "Value5", NULL, &type, (LPBYTE)path, &size);
4877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4878     ok(!memcmp(path, "one\0two\0three\0", size), "Wrong multi-sz data\n");
4879     ok(size == 15, "Expected 15, got %d\n", size);
4880     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4881
4882     size = MAX_PATH;
4883     type = 0xdeadbeef;
4884     memset(path, 'a', MAX_PATH);
4885     res = RegQueryValueExA(hkey, "Value6", NULL, &type, (LPBYTE)path, &size);
4886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4887     ok(!memcmp(path, "", size), "Wrong multi-sz data\n");
4888     ok(size == 1, "Expected 1, got %d\n", size);
4889     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4890
4891     size = MAX_PATH;
4892     type = 0xdeadbeef;
4893     memset(path, 'a', MAX_PATH);
4894     res = RegQueryValueExA(hkey, "Value7", NULL, &type, (LPBYTE)path, &size);
4895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4896     ok(!memcmp(path, "two\0", size), "Wrong multi-sz data\n");
4897     ok(size == 5, "Expected 5, got %d\n", size);
4898     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
4899
4900     RegDeleteValueA(hkey, "Value");
4901     RegDeleteValueA(hkey, "Value1");
4902     RegDeleteValueA(hkey, "Value2");
4903     RegDeleteValueA(hkey, "Value3");
4904     RegDeleteValueA(hkey, "Value4");
4905     RegDeleteValueA(hkey, "Value5");
4906     RegDeleteValueA(hkey, "Value6");
4907     RegDeleteValueA(hkey, "Value7");
4908     RegCloseKey(hkey);
4909     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
4910
4911 error:
4912     DeleteFile(msifile);
4913     DeleteFile("msitest\\augustus");
4914     RemoveDirectory("msitest");
4915 }
4916
4917 static void test_envvar(void)
4918 {
4919     static const char *results[] =
4920     {
4921         "1;2",    /* MSITESTVAR11 */
4922         "1",      /* MSITESTVAR12 */
4923         "1;2",    /* MSITESTVAR13 */
4924         ";1;",    /* MSITESTVAR14 */
4925         ";;1;;",  /* MSITESTVAR15 */
4926         " 1 ",    /* MSITESTVAR16 */
4927         ";;2;;1", /* MSITESTVAR17 */
4928         "1;;2;;", /* MSITESTVAR18 */
4929         "1",      /* MSITESTVAR19 */
4930         "1",      /* MSITESTVAR20 */
4931         NULL
4932     };
4933     UINT r;
4934     HKEY env;
4935     LONG res;
4936     DWORD type, size;
4937     char buffer[16];
4938     UINT i;
4939
4940     if (is_process_limited())
4941     {
4942         skip("process is limited\n");
4943         return;
4944     }
4945
4946     create_test_files();
4947     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
4948
4949     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
4950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4951
4952     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
4953     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4954
4955     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
4956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4957
4958     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4959
4960     r = MsiInstallProductA(msifile, NULL);
4961     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4962     {
4963         skip("Not enough rights to perform tests\n");
4964         goto error;
4965     }
4966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4967
4968     type = REG_NONE;
4969     size = sizeof(buffer);
4970     buffer[0] = 0;
4971     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
4972     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4973     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
4974     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
4975
4976     res = RegDeleteValueA(env, "MSITESTVAR1");
4977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4978
4979     type = REG_NONE;
4980     size = sizeof(buffer);
4981     buffer[0] = 0;
4982     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
4983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4984     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
4985     ok(!lstrcmp(buffer, "1"), "Expected \"1\", got %s\n", buffer);
4986
4987     res = RegDeleteValueA(env, "MSITESTVAR2");
4988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4989
4990     res = RegDeleteValueA(env, "MSITESTVAR3");
4991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4992
4993     res = RegDeleteValueA(env, "MSITESTVAR4");
4994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4995
4996     res = RegDeleteValueA(env, "MSITESTVAR5");
4997     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4998
4999     res = RegDeleteValueA(env, "MSITESTVAR6");
5000     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5001
5002     res = RegDeleteValueA(env, "MSITESTVAR7");
5003     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5004
5005     res = RegDeleteValueA(env, "MSITESTVAR8");
5006     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5007
5008     res = RegDeleteValueA(env, "MSITESTVAR9");
5009     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5010
5011     res = RegDeleteValueA(env, "MSITESTVAR10");
5012     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5013
5014     i = 11;
5015     while (results[i - 11])
5016     {
5017         char name[20];
5018         sprintf(name, "MSITESTVAR%d", i);
5019
5020         type = REG_NONE;
5021         size = sizeof(buffer);
5022         buffer[0] = 0;
5023         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
5024         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
5025         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
5026         ok(!lstrcmp(buffer, results[i - 11]), "%d: Expected %s, got %s\n", i, results[i - 11], buffer);
5027
5028         res = RegDeleteValueA(env, name);
5029         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
5030         i++;
5031     }
5032
5033     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
5034     delete_pf("msitest\\cabout\\new", FALSE);
5035     delete_pf("msitest\\cabout\\four.txt", TRUE);
5036     delete_pf("msitest\\cabout", FALSE);
5037     delete_pf("msitest\\changed\\three.txt", TRUE);
5038     delete_pf("msitest\\changed", FALSE);
5039     delete_pf("msitest\\first\\two.txt", TRUE);
5040     delete_pf("msitest\\first", FALSE);
5041     delete_pf("msitest\\filename", TRUE);
5042     delete_pf("msitest\\one.txt", TRUE);
5043     delete_pf("msitest\\service.exe", TRUE);
5044     delete_pf("msitest\\service2.exe", TRUE);
5045     delete_pf("msitest", FALSE);
5046
5047 error:
5048     RegDeleteValueA(env, "MSITESTVAR1");
5049     RegDeleteValueA(env, "MSITESTVAR2");
5050     RegCloseKey(env);
5051
5052     delete_test_files();
5053     DeleteFile(msifile);
5054 }
5055
5056 static void test_create_remove_folder(void)
5057 {
5058     UINT r;
5059
5060     if (is_process_limited())
5061     {
5062         skip("process is limited\n");
5063         return;
5064     }
5065
5066     CreateDirectoryA("msitest", NULL);
5067     CreateDirectoryA("msitest\\first", NULL);
5068     CreateDirectoryA("msitest\\second", NULL);
5069     create_file("msitest\\first\\one.txt", 1000);
5070     create_file("msitest\\second\\two.txt", 1000);
5071     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
5072
5073     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5074
5075     r = MsiInstallProductA(msifile, NULL);
5076     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5077     {
5078         skip("Not enough rights to perform tests\n");
5079         goto error;
5080     }
5081     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5082
5083     ok(pf_exists("msitest\\first\\one.txt"), "file not installed\n");
5084     ok(pf_exists("msitest\\first"), "directory not created\n");
5085     ok(pf_exists("msitest\\second\\two.txt"), "file not installed\n");
5086     ok(pf_exists("msitest\\second"), "directory not created\n");
5087     ok(pf_exists("msitest\\third"), "directory not created\n");
5088     ok(pf_exists("msitest"), "directory not created\n");
5089
5090     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5091     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5092
5093     ok(!pf_exists("msitest\\first\\one.txt"), "file not removed\n");
5094     ok(!pf_exists("msitest\\first"), "directory not removed\n");
5095     ok(!pf_exists("msitest\\second\\two.txt"), "file not removed\n");
5096     ok(!pf_exists("msitest\\second"), "directory not removed\n");
5097     ok(!pf_exists("msitest\\third"), "directory not removed\n");
5098     todo_wine ok(!pf_exists("msitest"), "directory not removed\n");
5099
5100 error:
5101     DeleteFileA("msitest\\first\\one.txt");
5102     DeleteFileA("msitest\\second\\two.txt");
5103     RemoveDirectoryA("msitest\\first");
5104     RemoveDirectoryA("msitest\\second");
5105     RemoveDirectoryA("msitest");
5106     DeleteFile(msifile);
5107 }
5108
5109 static void test_start_services(void)
5110 {
5111     UINT r;
5112     SC_HANDLE scm, service;
5113     BOOL ret;
5114     DWORD error = ERROR_SUCCESS;
5115
5116     scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5117     if (!scm && GetLastError() == ERROR_ACCESS_DENIED)
5118     {
5119         skip("Not enough rights to perform tests\n");
5120         return;
5121     }
5122     ok(scm != NULL, "Failed to open the SC Manager\n");
5123     if (!scm) return;
5124
5125     service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
5126     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
5127     {
5128         win_skip("The 'Spooler' service does not exist\n");
5129         CloseServiceHandle(scm);
5130         return;
5131     }
5132     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
5133     if (!service) {
5134         CloseServiceHandle(scm);
5135         return;
5136     }
5137
5138     ret = StartService(service, 0, NULL);
5139     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
5140     {
5141         skip("Spooler service not available, skipping test\n");
5142         CloseServiceHandle(service);
5143         CloseServiceHandle(scm);
5144         return;
5145     }
5146
5147     CloseServiceHandle(service);
5148     CloseServiceHandle(scm);
5149
5150     create_test_files();
5151     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
5152
5153     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5154
5155     r = MsiInstallProductA(msifile, NULL);
5156     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5157
5158     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5159     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5160     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5161     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5162     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5163     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5164     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5165     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5166     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5167     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5168     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5169     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5170     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5171
5172     delete_test_files();
5173     DeleteFile(msifile);
5174
5175     if (error == ERROR_SUCCESS)
5176     {
5177         SERVICE_STATUS status;
5178
5179         scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5180         service = OpenService(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
5181
5182         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
5183         ok(ret, "ControlService failed %u\n", GetLastError());
5184
5185         CloseServiceHandle(service);
5186         CloseServiceHandle(scm);
5187     }
5188 }
5189
5190 static void test_delete_services(void)
5191 {
5192     UINT r;
5193     SC_HANDLE manager, service;
5194     DWORD error;
5195
5196     if (is_process_limited())
5197     {
5198         skip("process is limited\n");
5199         return;
5200     }
5201
5202     manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5203     ok(manager != NULL, "can't open service manager %u\n", GetLastError());
5204     if (!manager) return;
5205
5206     service = CreateServiceA(manager, "TestService3", "TestService3",
5207         SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
5208         SERVICE_ERROR_NORMAL, "C:\\doesnt_exist.exe", NULL, NULL, NULL, NULL, NULL);
5209     ok(service != NULL, "can't create service %u\n", GetLastError());
5210     CloseServiceHandle(service);
5211     CloseServiceHandle(manager);
5212     if (!service) goto error;
5213
5214     create_test_files();
5215     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
5216
5217     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5218
5219     r = MsiInstallProductA(msifile, NULL);
5220     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5221     {
5222         skip("Not enough rights to perform tests\n");
5223         goto error;
5224     }
5225     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5226
5227     manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5228     ok(manager != NULL, "can't open service manager\n");
5229     if (!manager) goto error;
5230
5231     service = OpenServiceA(manager, "TestService3", GENERIC_ALL);
5232     error = GetLastError();
5233     ok(service == NULL, "TestService3 not deleted\n");
5234     ok(error == ERROR_SERVICE_DOES_NOT_EXIST, "wrong error %u\n", error);
5235     CloseServiceHandle(manager);
5236
5237     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5239
5240     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5241     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5242     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5243     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5244     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5245     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5246     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5247     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5248     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5249     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5250     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5251     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5252     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5253
5254 error:
5255     delete_test_files();
5256     DeleteFile(msifile);
5257 }
5258
5259 static void test_self_registration(void)
5260 {
5261     UINT r;
5262
5263     if (is_process_limited())
5264     {
5265         skip("process is limited\n");
5266         return;
5267     }
5268
5269     create_test_files();
5270     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
5271
5272     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5273
5274     r = MsiInstallProductA(msifile, NULL);
5275     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5276     {
5277         skip("Not enough rights to perform tests\n");
5278         goto error;
5279     }
5280     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5281
5282     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5283     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5284     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5285     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5286     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5287     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5288     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5289     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5290     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5291     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5292     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5293     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5294     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5295
5296 error:
5297     delete_test_files();
5298     DeleteFile(msifile);
5299 }
5300
5301 static void test_register_font(void)
5302 {
5303     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
5304     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
5305     LONG ret;
5306     HKEY key;
5307     UINT r;
5308     REGSAM access = KEY_ALL_ACCESS;
5309
5310     if (is_process_limited())
5311     {
5312         skip("process is limited\n");
5313         return;
5314     }
5315
5316     create_test_files();
5317     create_file("msitest\\font.ttf", 1000);
5318     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
5319
5320     if (is_wow64)
5321         access |= KEY_WOW64_64KEY;
5322
5323     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5324
5325     r = MsiInstallProductA(msifile, NULL);
5326     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5327     {
5328         skip("Not enough rights to perform tests\n");
5329         goto error;
5330     }
5331     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5332
5333     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont1, 0, access, &key);
5334     if (ret)
5335         RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont2, 0, access, &key);
5336
5337     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
5338     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
5339
5340     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5341     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5342
5343     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5344
5345     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
5346     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
5347
5348     RegDeleteValueA(key, "msi test font");
5349     RegCloseKey(key);
5350
5351 error:
5352     DeleteFileA("msitest\\font.ttf");
5353     delete_test_files();
5354     DeleteFile(msifile);
5355 }
5356
5357 static void test_validate_product_id(void)
5358 {
5359     UINT r;
5360
5361     if (is_process_limited())
5362     {
5363         skip("process is limited\n");
5364         return;
5365     }
5366
5367     create_test_files();
5368     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
5369
5370     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5371
5372     r = MsiInstallProductA(msifile, NULL);
5373     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5374     {
5375         skip("Not enough rights to perform tests\n");
5376         goto error;
5377     }
5378     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5379
5380     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
5381     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5382
5383     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
5384     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5385
5386     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
5387     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5388
5389     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5390     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5391     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5392     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5393     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5394     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5395     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5396     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5397     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5398     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5399     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5400     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5401     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5402
5403 error:
5404     delete_test_files();
5405     DeleteFile(msifile);
5406 }
5407
5408 static void test_install_remove_odbc(void)
5409 {
5410     UINT r;
5411
5412     if (is_process_limited())
5413     {
5414         skip("process is limited\n");
5415         return;
5416     }
5417
5418     create_test_files();
5419     create_file("msitest\\ODBCdriver.dll", 1000);
5420     create_file("msitest\\ODBCdriver2.dll", 1000);
5421     create_file("msitest\\ODBCtranslator.dll", 1000);
5422     create_file("msitest\\ODBCtranslator2.dll", 1000);
5423     create_file("msitest\\ODBCsetup.dll", 1000);
5424     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
5425
5426     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5427
5428     r = MsiInstallProductA(msifile, NULL);
5429     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5430     {
5431         skip("Not enough rights to perform tests\n");
5432         goto error;
5433     }
5434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5435
5436     ok(pf_exists("msitest\\ODBCdriver.dll"), "file not created\n");
5437     ok(pf_exists("msitest\\ODBCdriver2.dll"), "file not created\n");
5438     ok(pf_exists("msitest\\ODBCtranslator.dll"), "file not created\n");
5439     ok(pf_exists("msitest\\ODBCtranslator2.dll"), "file not created\n");
5440     ok(pf_exists("msitest\\ODBCsetup.dll"), "file not created\n");
5441
5442     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5444
5445     ok(!delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not removed\n");
5446     ok(!delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not removed\n");
5447     ok(!delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not removed\n");
5448     ok(!delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not removed\n");
5449     ok(!delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not removed\n");
5450     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5451
5452 error:
5453     DeleteFileA("msitest\\ODBCdriver.dll");
5454     DeleteFileA("msitest\\ODBCdriver2.dll");
5455     DeleteFileA("msitest\\ODBCtranslator.dll");
5456     DeleteFileA("msitest\\ODBCtranslator2.dll");
5457     DeleteFileA("msitest\\ODBCsetup.dll");
5458     delete_test_files();
5459     DeleteFile(msifile);
5460 }
5461
5462 static void test_register_typelib(void)
5463 {
5464     UINT r;
5465
5466     if (is_process_limited())
5467     {
5468         skip("process is limited\n");
5469         return;
5470     }
5471
5472     create_test_files();
5473     create_file("msitest\\typelib.dll", 1000);
5474     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
5475
5476     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5477
5478     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
5479     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5480     {
5481         skip("Not enough rights to perform tests\n");
5482         goto error;
5483     }
5484     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5485
5486     r = MsiInstallProductA(msifile, NULL);
5487     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5488
5489     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5490     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5491
5492     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
5493     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5494
5495 error:
5496     DeleteFileA("msitest\\typelib.dll");
5497     delete_test_files();
5498     DeleteFile(msifile);
5499 }
5500
5501 static void test_create_remove_shortcut(void)
5502 {
5503     UINT r;
5504
5505     if (is_process_limited())
5506     {
5507         skip("process is limited\n");
5508         return;
5509     }
5510
5511     create_test_files();
5512     create_file("msitest\\target.txt", 1000);
5513     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
5514
5515     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5516
5517     r = MsiInstallProductA(msifile, NULL);
5518     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5519     {
5520         skip("Not enough rights to perform tests\n");
5521         goto error;
5522     }
5523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5524
5525     ok(pf_exists("msitest\\target.txt"), "file not created\n");
5526     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
5527
5528     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5530
5531     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
5532     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
5533     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5534
5535 error:
5536     DeleteFileA("msitest\\target.txt");
5537     delete_test_files();
5538     DeleteFile(msifile);
5539 }
5540
5541 static void test_publish_components(void)
5542 {
5543     static char keypath[] =
5544         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
5545
5546     UINT r;
5547     LONG res;
5548     HKEY key;
5549
5550     if (is_process_limited())
5551     {
5552         skip("process is limited\n");
5553         return;
5554     }
5555
5556     create_test_files();
5557     create_file("msitest\\english.txt", 1000);
5558     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
5559
5560     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5561
5562     r = MsiInstallProductA(msifile, NULL);
5563     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5564     {
5565         skip("Not enough rights to perform tests\n");
5566         goto error;
5567     }
5568     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5569
5570     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
5571     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
5572
5573     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
5574     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
5575     RegCloseKey(key);
5576
5577     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5579
5580     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
5581     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
5582
5583     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
5584     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5585
5586 error:
5587     DeleteFileA("msitest\\english.txt");
5588     delete_test_files();
5589     DeleteFile(msifile);
5590 }
5591
5592 static void test_remove_duplicate_files(void)
5593 {
5594     UINT r;
5595
5596     if (is_process_limited())
5597     {
5598         skip("process is limited\n");
5599         return;
5600     }
5601
5602     create_test_files();
5603     create_file("msitest\\original.txt", 1000);
5604     create_file("msitest\\original2.txt", 1000);
5605     create_file("msitest\\original3.txt", 1000);
5606     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
5607
5608     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5609
5610     r = MsiInstallProductA(msifile, NULL);
5611     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5612     {
5613         skip("Not enough rights to perform tests\n");
5614         goto error;
5615     }
5616     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5617
5618     ok(pf_exists("msitest\\original.txt"), "file not created\n");
5619     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
5620     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
5621     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
5622     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
5623
5624     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5625     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5626
5627     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
5628     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
5629     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
5630     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
5631     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
5632     ok(delete_pf("msitest", FALSE), "directory removed\n");
5633
5634 error:
5635     DeleteFileA("msitest\\original.txt");
5636     DeleteFileA("msitest\\original2.txt");
5637     DeleteFileA("msitest\\original3.txt");
5638     delete_test_files();
5639     DeleteFile(msifile);
5640 }
5641
5642 static void test_remove_registry_values(void)
5643 {
5644     UINT r;
5645     LONG res;
5646     HKEY key;
5647     REGSAM access = KEY_ALL_ACCESS;
5648
5649     if (is_process_limited())
5650     {
5651         skip("process is limited\n");
5652         return;
5653     }
5654
5655     create_test_files();
5656     create_file("msitest\\registry.txt", 1000);
5657     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
5658
5659     if (is_wow64)
5660         access |= KEY_WOW64_64KEY;
5661
5662     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5663
5664     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, NULL, 0, access, NULL, &key, NULL);
5665     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
5666     RegCloseKey(key);
5667
5668     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL);
5669     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
5670     RegCloseKey(key);
5671
5672     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, NULL, 0, access, NULL, &key, NULL);
5673     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
5674     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
5675     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
5676     RegCloseKey(key);
5677
5678     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, NULL, 0, access, NULL, &key, NULL);
5679     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
5680     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
5681     RegCloseKey(key);
5682
5683     r = MsiInstallProductA(msifile, NULL);
5684     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5685     {
5686         skip("Not enough rights to perform tests\n");
5687         goto error;
5688     }
5689     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5690
5691     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, access, &key);
5692     ok(res == ERROR_SUCCESS, "key removed\n");
5693     RegCloseKey(key);
5694
5695     if (is_64bit)
5696     {
5697         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key2", 0, KEY_ALL_ACCESS, &key);
5698         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5699     }
5700     else
5701     {
5702         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, KEY_ALL_ACCESS, &key);
5703         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5704     }
5705
5706     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL);
5707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5708     RegCloseKey(key);
5709
5710     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5711     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5712
5713     if (is_64bit)
5714     {
5715         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key1", 0, KEY_ALL_ACCESS, &key);
5716         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5717     }
5718     else
5719     {
5720         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, KEY_ALL_ACCESS, &key);
5721         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5722     }
5723
5724     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, access, &key);
5725     ok(res == ERROR_SUCCESS, "key removed\n");
5726     RegCloseKey(key);
5727
5728     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, access, &key);
5729     ok(res == ERROR_SUCCESS, "key removed\n");
5730     RegCloseKey(key);
5731
5732     if (is_64bit)
5733     {
5734         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key);
5735         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5736     }
5737     else
5738     {
5739         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key);
5740         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
5741     }
5742
5743     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access);
5744     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access);
5745     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine", access);
5746
5747     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
5748     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5749
5750 error:
5751     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", access);
5752     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access);
5753     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access);
5754     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", access);
5755
5756     DeleteFileA("msitest\\registry.txt");
5757     delete_test_files();
5758     DeleteFile(msifile);
5759 }
5760
5761 static void test_find_related_products(void)
5762 {
5763     UINT r;
5764
5765     if (is_process_limited())
5766     {
5767         skip("process is limited\n");
5768         return;
5769     }
5770
5771     create_test_files();
5772     create_file("msitest\\product.txt", 1000);
5773     create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table));
5774
5775     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5776
5777     r = MsiInstallProductA(msifile, NULL);
5778     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5779     {
5780         skip("Not enough rights to perform tests\n");
5781         goto error;
5782     }
5783     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5784
5785     /* install again, so it finds the upgrade code */
5786     r = MsiInstallProductA(msifile, NULL);
5787     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5788
5789     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5790     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5791
5792     ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n");
5793     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5794
5795 error:
5796     DeleteFileA("msitest\\product.txt");
5797     delete_test_files();
5798     DeleteFile(msifile);
5799 }
5800
5801 static void test_remove_ini_values(void)
5802 {
5803     UINT r;
5804     DWORD len;
5805     char inifile[MAX_PATH], buf[0x10];
5806     HANDLE file;
5807     BOOL ret;
5808
5809     if (is_process_limited())
5810     {
5811         skip("process is limited\n");
5812         return;
5813     }
5814
5815     create_test_files();
5816     create_file("msitest\\inifile.txt", 1000);
5817     create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table));
5818
5819     lstrcpyA(inifile, PROG_FILES_DIR);
5820     lstrcatA(inifile, "\\msitest");
5821     ret = CreateDirectoryA(inifile, NULL);
5822     if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
5823     {
5824         skip("Not enough rights to perform tests\n");
5825         goto error;
5826     }
5827     lstrcatA(inifile, "\\test.ini");
5828     file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
5829     CloseHandle(file);
5830
5831     ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile);
5832     ok(ret, "failed to write profile string %u\n", GetLastError());
5833
5834     ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile);
5835     ok(ret, "failed to write profile string %u\n", GetLastError());
5836
5837     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5838
5839     r = MsiInstallProductA(msifile, NULL);
5840     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5841
5842     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
5843     ok(len == 6, "got %u expected 6\n", len);
5844
5845     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
5846     ok(!len, "got %u expected 0\n", len);
5847
5848     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5849     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5850
5851     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
5852     ok(!len, "got %u expected 0\n", len);
5853
5854     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
5855     ok(!len, "got %u expected 0\n", len);
5856
5857     todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n");
5858     ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n");
5859     ok(delete_pf("msitest", FALSE), "directory removed\n");
5860
5861 error:
5862     DeleteFileA("msitest\\inifile.txt");
5863     delete_test_files();
5864     DeleteFile(msifile);
5865 }
5866
5867 static void test_remove_env_strings(void)
5868 {
5869     UINT r;
5870     LONG res;
5871     HKEY key;
5872     DWORD type, size;
5873     char buffer[0x10];
5874
5875     if (is_process_limited())
5876     {
5877         skip("process is limited\n");
5878         return;
5879     }
5880
5881     create_test_files();
5882     create_file("msitest\\envvar.txt", 1000);
5883     create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table));
5884
5885     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5886
5887     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5888     ok(!res, "failed to open environment key %d\n", res);
5889
5890     RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2);
5891     RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2);
5892     RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2);
5893     RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2);
5894     RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2);
5895
5896     RegCloseKey(key);
5897
5898     r = MsiInstallProductA(msifile, NULL);
5899     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5900     {
5901         skip("Not enough rights to perform tests\n");
5902         goto error;
5903     }
5904     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5905
5906     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5907     ok(!res, "failed to open environment key %d\n", res);
5908
5909     type = REG_NONE;
5910     buffer[0] = 0;
5911     size = sizeof(buffer);
5912     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
5913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5914     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5915     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5916
5917     type = REG_NONE;
5918     buffer[0] = 0;
5919     size = sizeof(buffer);
5920     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
5921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5922     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5923     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5924
5925     type = REG_NONE;
5926     buffer[0] = 0;
5927     size = sizeof(buffer);
5928     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
5929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5930     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5931     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5932
5933     type = REG_NONE;
5934     buffer[0] = 0;
5935     size = sizeof(buffer);
5936     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size);
5937     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5938     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5939     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5940
5941     type = REG_NONE;
5942     buffer[0] = 0;
5943     size = sizeof(buffer);
5944     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
5945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5946     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5947     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5948
5949     RegCloseKey(key);
5950
5951     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5953
5954     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
5955     ok(!res, "failed to open environment key %d\n", res);
5956
5957     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL);
5958     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5959
5960     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL);
5961     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5962
5963     type = REG_NONE;
5964     buffer[0] = 0;
5965     size = sizeof(buffer);
5966     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
5967     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5968     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5969     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5970     RegDeleteValueA(key, "MSITESTVAR3");
5971
5972     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL);
5973     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5974
5975     type = REG_NONE;
5976     buffer[0] = 0;
5977     size = sizeof(buffer);
5978     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
5979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5980     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
5981     ok(!lstrcmp(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
5982     RegDeleteValueA(key, "MSITESTVAR5");
5983
5984     ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n");
5985     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5986
5987 error:
5988     RegDeleteValueA(key, "MSITESTVAR1");
5989     RegDeleteValueA(key, "MSITESTVAR2");
5990     RegDeleteValueA(key, "MSITESTVAR3");
5991     RegDeleteValueA(key, "MSITESTVAR4");
5992     RegDeleteValueA(key, "MSITESTVAR5");
5993     RegCloseKey(key);
5994
5995     DeleteFileA("msitest\\envvar.txt");
5996     delete_test_files();
5997     DeleteFile(msifile);
5998 }
5999
6000 static void test_register_class_info(void)
6001 {
6002     UINT r;
6003     LONG res;
6004     HKEY hkey;
6005
6006     if (is_process_limited())
6007     {
6008         skip("process is limited\n");
6009         return;
6010     }
6011
6012     create_test_files();
6013     create_file("msitest\\class.txt", 1000);
6014     create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table));
6015
6016     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6017
6018     r = MsiInstallProductA(msifile, NULL);
6019     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6020     {
6021         skip("Not enough rights to perform tests\n");
6022         goto error;
6023     }
6024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6025
6026     if (is_64bit)
6027         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6028     else
6029         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6030     ok(res == ERROR_SUCCESS, "key not created\n");
6031     RegCloseKey(hkey);
6032
6033     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6034     ok(res == ERROR_SUCCESS, "key not created\n");
6035     RegCloseKey(hkey);
6036
6037     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
6038     ok(res == ERROR_SUCCESS, "key not created\n");
6039     RegCloseKey(hkey);
6040
6041     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6043
6044     if (is_64bit)
6045         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6046     else
6047         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6048     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6049
6050     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6051     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6052
6053     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
6054     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6055
6056     ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n");
6057     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6058
6059 error:
6060     DeleteFileA("msitest\\class.txt");
6061     delete_test_files();
6062     DeleteFile(msifile);
6063 }
6064
6065 static void test_register_extension_info(void)
6066 {
6067     UINT r;
6068     LONG res;
6069     HKEY hkey;
6070
6071     if (is_process_limited())
6072     {
6073         skip("process is limited\n");
6074         return;
6075     }
6076
6077     create_test_files();
6078     create_file("msitest\\extension.txt", 1000);
6079     create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table));
6080
6081     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6082
6083     r = MsiInstallProductA(msifile, NULL);
6084     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6085     {
6086         skip("Not enough rights to perform tests\n");
6087         goto error;
6088     }
6089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6090
6091     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
6092     ok(res == ERROR_SUCCESS, "key not created\n");
6093     RegCloseKey(hkey);
6094
6095     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey);
6096     ok(res == ERROR_SUCCESS, "key not created\n");
6097     RegCloseKey(hkey);
6098
6099     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6101
6102     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
6103     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6104
6105     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey);
6106     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6107
6108     ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n");
6109     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6110
6111 error:
6112     DeleteFileA("msitest\\extension.txt");
6113     delete_test_files();
6114     DeleteFile(msifile);
6115 }
6116
6117 static void test_register_mime_info(void)
6118 {
6119     UINT r;
6120     LONG res;
6121     HKEY hkey;
6122
6123     if (is_process_limited())
6124     {
6125         skip("process is limited\n");
6126         return;
6127     }
6128
6129     create_test_files();
6130     create_file("msitest\\mime.txt", 1000);
6131     create_database(msifile, rmi_tables, sizeof(rmi_tables) / sizeof(msi_table));
6132
6133     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6134
6135     r = MsiInstallProductA(msifile, NULL);
6136     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6137     {
6138         skip("Not enough rights to perform tests\n");
6139         goto error;
6140     }
6141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6142
6143     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
6144     ok(res == ERROR_SUCCESS, "key not created\n");
6145     RegCloseKey(hkey);
6146
6147     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6148     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6149
6150     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
6151     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6152
6153     ok(!delete_pf("msitest\\mime.txt", TRUE), "file not removed\n");
6154     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6155
6156 error:
6157     DeleteFileA("msitest\\mime.txt");
6158     delete_test_files();
6159     DeleteFile(msifile);
6160 }
6161
6162 static void test_publish_assemblies(void)
6163 {
6164     static const char manifest[] =
6165         "<assemblyIdentity type=\"win32\" name=\"Wine.Win32.Assembly\" "
6166         "version=\"1.0.0.0\" publicKeyToken=\"abcdef0123456789\" "
6167         "processorArchitecture=\"x86\"/>";
6168     static const char manifest_local[] =
6169         "<assemblyIdentity type=\"win32\" name=\"Wine.Win32.Local.Assembly\" "
6170         "version=\"1.0.0.0\" publicKeyToken=\"abcdef0123456789\" "
6171         "processorArchitecture=\"x86\"/>";
6172     static const char classes_path_dotnet[] =
6173         "Installer\\Assemblies\\Global";
6174     static const char classes_path_dotnet_local[] =
6175         "Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt";
6176     static const char classes_path_dotnet_local_wow64[] =
6177         "Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt";
6178     static const char classes_path_win32[] =
6179         "Installer\\Win32Assemblies\\Global";
6180     static const char classes_path_win32_local[] =
6181         "Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt";
6182     static const char classes_path_win32_local_wow64[] =
6183         "Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt";
6184     static const char path_dotnet[] =
6185         "Software\\Microsoft\\Installer\\Assemblies\\Global";
6186     static const char path_dotnet_local[] =
6187         "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt";
6188     static const char path_dotnet_local_wow64[] =
6189         "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt";
6190     static const char path_win32[] =
6191         "Software\\Microsoft\\Installer\\Win32Assemblies\\Global";
6192     static const char path_win32_local[] =
6193         "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt";
6194     static const char path_win32_local_wow64[] =
6195         "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt";
6196     static const char name_dotnet[] =
6197         "Wine.Dotnet.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\","
6198         "version=\"1.0.0.0\",culture=\"neutral\"";
6199     static const char name_dotnet_local[] =
6200         "Wine.Dotnet.Local.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\","
6201         "version=\"1.0.0.0\",culture=\"neutral\"";
6202     static const char name_win32[] =
6203         "Wine.Win32.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\","
6204         "type=\"win32\",version=\"1.0.0.0\"";
6205     static const char name_win32_local[] =
6206         "Wine.Win32.Local.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\","
6207         "type=\"win32\",version=\"1.0.0.0\"";
6208     UINT r;
6209     LONG res;
6210     HKEY hkey;
6211     const char *path;
6212     int access;
6213
6214     if (is_process_limited())
6215     {
6216         skip("process is limited\n");
6217         return;
6218     }
6219
6220     create_test_files();
6221     create_file("msitest\\win32.txt", 1000);
6222     create_file("msitest\\win32_local.txt", 1000);
6223     create_file("msitest\\dotnet.txt", 1000);
6224     create_file("msitest\\dotnet_local.txt", 1000);
6225     create_file_data("msitest\\manifest.txt", manifest, 0);
6226     create_file_data("msitest\\manifest_local.txt", manifest_local, 0);
6227     create_file("msitest\\application_win32.txt", 1000);
6228     create_file("msitest\\application_dotnet.txt", 1000);
6229     create_database(msifile, pa_tables, sizeof(pa_tables) / sizeof(msi_table));
6230
6231     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6232
6233     r = MsiInstallProductA(msifile, NULL);
6234     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6235     {
6236         skip("Not enough rights to perform tests\n");
6237         goto done;
6238     }
6239     if (r == ERROR_INSTALL_FAILURE)
6240     {
6241         skip("No support for installing side-by-side assemblies\n");
6242         goto done;
6243     }
6244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6245
6246     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey);
6247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6248     CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
6249     RegCloseKey(hkey);
6250
6251     path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local;
6252     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
6253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6254     CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox");
6255     RegCloseKey(hkey);
6256
6257     res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey);
6258     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
6259        "Expected ERROR_SUCCESS, got %d\n", res);
6260     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%");
6261     RegCloseKey(hkey);
6262
6263     path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local;
6264     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
6265     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
6266        "Expected ERROR_SUCCESS, got %d\n", res);
6267     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!");
6268     RegCloseKey(hkey);
6269
6270     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6271     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6272
6273     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey);
6274     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
6275     if (res == ERROR_SUCCESS)
6276     {
6277         res = RegDeleteValueA(hkey, name_dotnet);
6278         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6279         RegCloseKey(hkey);
6280     }
6281
6282     path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local;
6283     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
6284     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6285
6286     res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey);
6287     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
6288     if (res == ERROR_SUCCESS)
6289     {
6290         res = RegDeleteValueA(hkey, name_win32);
6291         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6292         RegCloseKey(hkey);
6293     }
6294
6295     path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local;
6296     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
6297     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6298
6299     r = MsiInstallProductA(msifile, "ALLUSERS=1");
6300     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6301
6302     access = KEY_QUERY_VALUE;
6303     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey);
6304     if (res == ERROR_FILE_NOT_FOUND && is_wow64) /* Vista WOW64 */
6305     {
6306         trace("Using 64-bit registry view for HKCR\\Installer\n");
6307         access = KEY_QUERY_VALUE | KEY_WOW64_64KEY;
6308         res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey);
6309     }
6310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6311     CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
6312     RegCloseKey(hkey);
6313
6314     path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local;
6315     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey);
6316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6317     CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox");
6318     RegCloseKey(hkey);
6319
6320     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_win32, 0, access, &hkey);
6321     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
6322        "Expected ERROR_SUCCESS, got %d\n", res);
6323     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%");
6324     RegCloseKey(hkey);
6325
6326     path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local;
6327     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey);
6328     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
6329        "Expected ERROR_SUCCESS, got %d\n", res);
6330     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!");
6331     RegCloseKey(hkey);
6332
6333     r = MsiInstallProductA(msifile, "REMOVE=ALL ALLUSERS=1");
6334     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6335
6336     res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_dotnet, &hkey);
6337     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
6338     if (res == ERROR_SUCCESS)
6339     {
6340         res = RegDeleteValueA(hkey, name_dotnet);
6341         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6342         RegCloseKey(hkey);
6343     }
6344
6345     path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local;
6346     res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey);
6347     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6348
6349     res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_win32, &hkey);
6350     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
6351     if (res == ERROR_SUCCESS)
6352     {
6353         res = RegDeleteValueA(hkey, name_win32);
6354         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6355         RegCloseKey(hkey);
6356     }
6357
6358     path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local;
6359     res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey);
6360     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6361
6362 done:
6363     DeleteFileA("msitest\\win32.txt");
6364     DeleteFileA("msitest\\win32_local.txt");
6365     DeleteFileA("msitest\\dotnet.txt");
6366     DeleteFileA("msitest\\dotnet_local.txt");
6367     DeleteFileA("msitest\\manifest.txt");
6368     DeleteFileA("msitest\\manifest_local.txt");
6369     DeleteFileA("msitest\\application_win32.txt");
6370     DeleteFileA("msitest\\application_dotnet.txt");
6371     delete_test_files();
6372     DeleteFile(msifile);
6373 }
6374
6375 static void test_remove_existing_products(void)
6376 {
6377     UINT r;
6378
6379     if (is_process_limited())
6380     {
6381         skip("process is limited\n");
6382         return;
6383     }
6384
6385     create_test_files();
6386     create_file("msitest\\rep.txt", 1000);
6387     create_database(msifile, rep_tables, sizeof(rep_tables) / sizeof(msi_table));
6388
6389     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6390
6391     r = MsiInstallProductA(msifile, NULL);
6392     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6393     {
6394         skip("Not enough rights to perform tests\n");
6395         goto error;
6396     }
6397     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6398
6399     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6401
6402     ok(!delete_pf("msitest\\rep.txt", TRUE), "file not removed\n");
6403     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6404
6405 error:
6406     DeleteFileA("msitest\\rep.txt");
6407     delete_test_files();
6408     DeleteFile(msifile);
6409 }
6410
6411 START_TEST(action)
6412 {
6413     DWORD len;
6414     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
6415     STATEMGRSTATUS status;
6416     BOOL ret = FALSE;
6417
6418     init_functionpointers();
6419
6420     if (pIsWow64Process)
6421         pIsWow64Process(GetCurrentProcess(), &is_wow64);
6422
6423     GetCurrentDirectoryA(MAX_PATH, prev_path);
6424     GetTempPath(MAX_PATH, temp_path);
6425     SetCurrentDirectoryA(temp_path);
6426
6427     lstrcpyA(CURR_DIR, temp_path);
6428     len = lstrlenA(CURR_DIR);
6429
6430     if(len && (CURR_DIR[len - 1] == '\\'))
6431         CURR_DIR[len - 1] = 0;
6432
6433     ok(get_system_dirs(), "failed to retrieve system dirs\n");
6434     ok(get_user_dirs(), "failed to retrieve user dirs\n");
6435
6436     /* Create a restore point ourselves so we circumvent the multitude of restore points
6437      * that would have been created by all the installation and removal tests.
6438      *
6439      * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
6440      * creation of restore points.
6441      */
6442     if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
6443     {
6444         memset(&status, 0, sizeof(status));
6445         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
6446     }
6447
6448     /* Create only one log file and don't append. We have to pass something
6449      * for the log mode for this to work. The logfile needs to have an absolute
6450      * path otherwise we still end up with some extra logfiles as some tests
6451      * change the current directory.
6452      */
6453     lstrcpyA(log_file, temp_path);
6454     lstrcatA(log_file, "\\msitest.log");
6455     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
6456
6457     test_register_product();
6458     test_publish_product();
6459     test_publish_features();
6460     test_register_user();
6461     test_process_components();
6462     test_publish();
6463     test_publish_sourcelist();
6464     test_remove_files();
6465     test_move_files();
6466     test_duplicate_files();
6467     test_write_registry_values();
6468     test_envvar();
6469     test_create_remove_folder();
6470     test_start_services();
6471     test_delete_services();
6472     test_self_registration();
6473     test_register_font();
6474     test_validate_product_id();
6475     test_install_remove_odbc();
6476     test_register_typelib();
6477     test_create_remove_shortcut();
6478     test_publish_components();
6479     test_remove_duplicate_files();
6480     test_remove_registry_values();
6481     test_find_related_products();
6482     test_remove_ini_values();
6483     test_remove_env_strings();
6484     test_register_class_info();
6485     test_register_extension_info();
6486     test_register_mime_info();
6487     test_publish_assemblies();
6488     test_remove_existing_products();
6489
6490     DeleteFileA(log_file);
6491
6492     if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
6493     {
6494         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
6495         if (ret)
6496             remove_restore_point(status.llSequenceNumber);
6497     }
6498     FreeLibrary(hsrclient);
6499
6500     SetCurrentDirectoryA(prev_path);
6501 }