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