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