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