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