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